開発者ブログ

ユーザー目線に立った使い心地の良いユーザビリティの設計と、Javaのオブジェクト指向を駆使して、パフォーマンスの最大化を追及。STSD株式会社の開発エンジニアによるブログです。

[AWS] JavaからAmazon SQSのメッセージ送受信を行う

Javaを使用してAmazon SQSのキューにメッセージの送信、キューからの受信を行ってみました。

  • 2018年 08月 01日
SQS(Simple Queue Service)は自動でスケーリング等を行ってくれる完全マネージド型のメッセージキューイングサービスで、アプリケーションなどからメッセージのキューイング処理を切り離して運用することが可能です。
AWSではこのSQSとSimple Notification Service(SNS)などを組み合わせることで、AWS自身から発せられるイベントの情報を一旦キューイングしておいて、アプリケーションから順次処理をしたりすることが可能になり、システム間の非同期なメッセージ処理を比較的容易に構築することができます。

今回はこのSQSへメッセージの送信をしたり、受信することをJavaから行ってみます。

キューの追加

SQSではキューイングするメッセージを入れる箱を「キュー」と呼びます。
まずはこの「キュー」をAWS上に作成します。

AWSのコンソールから「Simple Queue Service」を開いて「新しいキューの作成」をクリックします。


「キュー名」に作成するキューの名前を入力します。


「キューの作成」をクリックしてキューを作成します。


以上でキューが作成できました。

ユーザー権限の設定

Javaで使用するユーザーに下記のポリシーを追加します。
※[アカウントID] はご自身のものに置き換えて下さい。
※「ap-northeast-1」はキューを作成したリージョンです。異なる場合は書き換えてください。

このポリシーでは「ap-northeast-1」(東京)リージョンの「devblog」キューに、メッセージを送信する「SendMessage」、メッセージを受信する「ReceiveMessage」、メッセージを削除する「DeleteMessage」を有効にしています。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "sqs:DeleteMessage",
                "sqs:ReceiveMessage",
                "sqs:SendMessage"
            ],
            "Resource": "arn:aws:sqs:ap-northeast-1:[アカウントID]:devblog"
        }
    ]
}

SQSの権限設定

SQSにはJavaで使用するユーザーからのアクセスを許可するように設定します。

まずはSQSの管理コンソールからキューを選択し、「アクセス許可」タブを開きます。



「アクセス許可の追加」をクリックします。


「プリンシパル」にAWSのアカウントIDを入力、「すべてのSQSアクション」を選択します。
そして「条件」に「ArnEquals」、「キー」に「aws:SourceArn」、「値」に「arn:aws:iam::[アカウントID]:user/[ユーザー名]」を入力します。
※[アカウントID] と [ユーザー名] は使用する環境に合わせて適宜置き換えてください。


「条件の追加」をクリック、「アクセス許可の追加」をクリックします。


以上で設定は完了です。

クライアントの用意

ここからはJavaの実装例になります。

まずはSQSにアクセスするためのクライアントを用意します。
このクライアントからSQSに関するAPIの使用が可能となります。
// 認証情報を用意
AWSCredentials credentials = new BasicAWSCredentials(
	// アクセスキー
	"********************",
	// シークレットキー
	"****************************************"
);

// クライアントを生成
client = AmazonSQSClientBuilder
	.standard()
	.withCredentials(new AWSStaticCredentialsProvider(credentials))
	.withRegion(Regions.AP_NORTHEAST_1.getName())
	.build();

メッセージの送信

キューへのメッセージ送信は sendMessage メソッドで行います。
SendMessageRequest を使うとメッセージ送信時に細かな条件を指定することが可能です。
// 詳細な条件を指定してメッセージを送信する場合
SendMessageRequest request = 
	new SendMessageRequest()
		.withQueueUrl(QUEUE_URL)
		.withDelaySeconds(10)	// 10秒間遅延させる(不可視にする)
		.withMessageBody("サンプルメッセージA " + System.currentTimeMillis());
client.sendMessage(request);

// シンプルにメッセージを送信する場合
client.sendMessage(QUEUE_URL, "サンプルメッセージB " + System.currentTimeMillis());

コードの中に出てくる「QUEUE_URL」はキューごとに割り当てられているURLです。
SQSのコンソールに表示される下記がURLになります。

メッセージの受信

キューからのメッセージ受信は receiveMessage メソッドで行います。
ReceiveMessageRequest を使うことで細かな条件を指定することが可能です。
ReceiveMessageRequest request = 
	new ReceiveMessageRequest()
		.withQueueUrl(QUEUE_URL)
		.withWaitTimeSeconds(5)	// 最大5秒間のロングポーリングを行う
		.withMaxNumberOfMessages(10);	// 最大10件のメッセージを取得する

ReceiveMessageResult result = client.receiveMessage(request);

for (Message message : result.getMessages()) {
	System.out.println("Message ID: " +  message.getMessageId());
	System.out.println("Receipt Handle: " + message.getReceiptHandle());
	System.out.println("Message Body: " +  message.getBody());
}
※ロングポーリングを使用すると、キュー上にメッセージが無い場合に指定した時間メッセージが来るのを待つことが出来るようになります。

メッセージの削除

メッセージの削除は deleteMessage メソッドで行います。
削除対象のメッセージは「メッセージの受信」で受信したメッセージから取得できる ReceiptHandle と呼ばれるIDを指定します。
// メッセージの削除
client.deleteMessage(QUEUE_URL, message.getReceiptHandle());
今回はこれで以上です。