AWS SDK for JavaでAmazon SQSを使う
前回、Amazon SQSの記事で、Perlから使う方法を紹介しましたが、今日はJavaから
使う方法を紹介したいと思います。
というのはフレクトでは、Web系のアプリケーション構築はJavaで作ることが多いからです。
Perlはサーバの運用・管理のツールとして使うケースが多いです。
なお、Amazon SQSの本ブログでの紹介は以下のページを参照してください。
http://blog.flect.co.jp/cto/2010/09/amazon-sqs-4938.html
■ AWS SDK for Java
JavaからAmazon Web Servicesを操作するには、Amazon純正のSDKである
「AWS SDK for Java」を使います。以下からダウンロードできます。
http://aws.amazon.com/sdkforjava/
他にもPHP、Ruby、.NETなどの純正SDKがあります。
■ 使うための準備
AWS SDK for Javaの現在のバージョンは1.0.14です。aws-java-sdk-1.0.14.jarというファイルが
ダウンロードできると思います。これをクラスパスに通しましょう。
また、CommonsのHTTPクライアントライブラリやCODECライブラリが必要になるので
それぞれ以下からダウンロードしてクラスパスに通しましょう。
http://hc.apache.org/httpclient-3.x/
http://commons.apache.org/codec/
これで、コードを書き始められます。
■ 最初にアクセスキー、秘密キーのセットアップ
最初にアクセスキーと秘密キーを指定して、AWSCredentialという認証情報を持つインタフェースを実装しているBasicAWSCredentialsクラスのインスタンスを作成します。
そして、認証情報を引数にしてAmazonSQSClientというSQSのクライアントクラスの
インスタンスを作成します。
ちなみに、この手順はAmazonS3Clientなどでも同じような手順になります。
AWSCredentialを実装しているクラスにはPropertiesCredentialというプロパティファイルに
キー情報を保持して、それを読み取る実装クラスもあります。
String accessKey = "xxxxx"; // アクセスキーの設定
String secretKey = "xxxxx"; // 秘密キーの設定
// SQSのクライアントを作成。
AmazonSQS sqs = new AmazonSQSClient(new BasicAWSCredentials(accessKey,secretKey));
■ エンドポイントURLでRegionの指定
アメリカ東海岸、西海岸、シンガポールなど、どこのSQSサーバを使うか指定します。
// アメリカ西海岸を指定する。
sqs.setEndpoint("sqs.us-west-1.amazonaws.com");
ちなみに各Regionの指定は以下のURLです。
・アメリカ東海岸(US-East):sqs.us-east-1.amazonaws.com
・アメリカ西海岸(US-West):sqs.us-west-1.amazonaws.com
・シンガポール(Asia Pacific):sqs.ap-southeast-1.amazonaws.com
・ヨーロッパ(EU):sqs.eu-west-1.amazonaws.com
■ キューを作成する
エンドポイントを作成したら、いよいよキューを作成しましょう。以下のようにさくせいする。
視認性の秒数は、あるクライアントがキューのメッセージをReceiveしたときに、ここで指定した
秒数分は他のクライアントからReceiveできない(見えなくなる)、というものです。デフォルトは
30秒です。キューのURLはこのあと、メッセージの受け渡しをするときに使います。
// キュー作成のリクエスト作成。第2引数は視認性の秒数。
CreateQueueRequest createQueueRequest = new CreateQueueRequest("FlectQueue", 30); // キューを作成する。 CreateQueueResult createQueueResult = sqs.createQueue(createQueueRequest); // キューのURLを取得。この後のリクエストで使います。 String queueUrl = createQueueResult.getQueueUrl();
■ メッセージをキューに送信する
以下のように、SendMessageRequestクラスでリクエスト用のインスタンスを設定し、先ほど作成したキューのURLを指定します。そして、メッセージ内容を setMessageBody で指定して、最初に作成した
AmazonSQSClientのインスタンス(sqs)からメッセージをキューに送信します。
SendMessageRequest sendMessageRequest = new SendMessageRequest(); // 作成したキューURLを指定する。
sendMessageRequest.setQueueUrl(queueUrl);
// メッセージ内容をリクエストにセットする。
sendMessageRequest.setMessageBody("Hello, World");
// キューにメッセージを入れる。メッセージ結果を取得するとメッセージIDを取得できます。
SendMessageResult sendMessageResult = sqs.sendMessage(sendMessageRequest);
System.out.println(sendMessageResult.getMessageId());
■ キューからメッセージを受信し、処理が終わったら削除する
キューに入っているメッセージは他のワーカープロセス等で処理するのが一般的だと思います。
メッセージを取得する側を書いてみます。途中まではメッセージ送信と同じですね。
受信側特有なのは receiveMessageRequest.setMaxNumberOfMessages の部分で、メッセージ取得数をセットできる部分です。リクエスト送信後はforループにあるように、最大で指定した数分のメッセージを取得し、その結果をハンドリングできます。
取得したメッセージからは MessageクラスのgetReceiptHandle()メソッドを使うことで
メッセージのReceiptHandleを取得できます。メッセージに対応する処理が終わったら、
このReceiptHandleを指定して、キューからメッセージを削除します。
メッセージを削除しないと、キュー作成時に指定した視認性の秒数を経過したら、他のクライアントから同じメッセージを取得できてしまうので、きちんと削除したほうがよいです。
(ただ、同じメッセージを取得してもシステムとして挙動がおかしくならないようにはしないといけません)
// リクエストクラスのインスタンスを作成。 ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(); // キューのURLをセット。 receiveMessageRequest.setQueueUrl(queueUrl); // 1回のリクエストで取得できるメッセージの最大数を指定。 receiveMessageRequest.setMaxNumberOfMessages(10); // メッセージ取得。 ReceiveMessageResult receiveMessageResult = sqs.receiveMessage(receiveMessageRequest); // getMessagesで複数のメッセージのリストが返ってきます。 for (Message message : receiveMessageResult.getMessages()) { // ReceiptHandleはメッセージの削除を行うために必要になるハンドルです。 System.out.println("ReceiptHandle : " + message.getReceiptHandle()); System.out.println("MessageId : " + message.getMessageId()); System.out.println("MessageBody : " + message.getBody()); // ここで何かしらのメッセージに対する(重めの)処理をします。 doSomething(); // 処理が終わったらキューからメッセージを消します。 DeleteMessageRequest deleteMessageRequest = new DeleteMessageRequest(); // QueueのURLを設定します。 deleteMessageRequest.setQueueUrl(queueUrl); // ReceiptHandleを設定します。 deleteMessageRequest.setReceiptHandle(message.getReceiptHandle()); // そして、メッセージの削除をします。 sqs.deleteMessage(deleteMessageRequest); }
■ with***メソッドを使ってコンパクトにキュー操作処理を呼び出す
ここまでの例はキュー作成、メッセージ送信、メッセージ受信、いずれもだいたい以下の流れで処理をしてました。
(1) リクエストクラスのインスタンス作成(****Requestクラスをnewする)
(2) リクエストインスタンスにキューURLなどパラメータをセット(set***メソッド)
(3) AmazonSQSClientインスタンスのcreateQueue, sendMessageなどのメソッドでリクエストインスタンスを指定し、実行
この流れを、リクエストクラスのwith****メソッドを使うことでコンパクトにできます。
以下にメッセージ送信を例に紹介します。
SendMessageResult sendMessageResult = sqs.sendMessage( new SendMessageRequest() .withQueueUrl(queueUrl) .withMessageBody("Hello World") );
少しコンパクトになった感じがしますね。
■ まとめ
AWS for Javaを使ってAmazon SQSを操作する方法を書きました。Amazon純正のSDKだけあってS3など他のサービスについても使い方に統一感があり、何かと使いやすいです。
このブログでPerl関連でサンプルを書いていたのですが、社員がJava好きが多いので、
S3、EBS、IAMなど他のサービスについても調査をしてなるべくJavaで使い方など
ブログに書いていきたいと思います。
■ 参考リンク
http://aws.amazon.com/articles/3586
http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/
コメント