日. 1月 29th, 2023

tl;dr;

AWS SQSを使ったシステムを作る際、ローカル環境で手軽にSQSがいじれれば非常に便利だ。今回、Dockerを用いてSQS互換の環境を作った。
docker imageの作り方、localでの起動方法までまとめている。

docker image作成

SQSのinterfaceに適合したアプリケーションがある。

https://github.com/softwaremill/elasticmq

これをそのままDockerの中に入れ、ポートを開いて`ENTRYPOINT`を起動すれば、SQS互換のdocker imageを作成することができる。

FROM java:8

ADD https://s3-eu-west-1.amazonaws.com/softwaremill-public/elasticmq-server-0.15.3.jar /elasticmq/elasticmq-server-0.15.3.jar
EXPOSE 9324
ENTRYPOINT ["java","-jar","/elasticmq/elasticmq-server-0.15.3.jar"]

ビルド方法はこちら。

`docker build -t tsukada/elasticmq:0.15.3 .`

そのimageを用いて起動する。ローカルの9324 portがコンテナ内の9324 portにそのままマッピングさせた。

`docker run -d –name=elasticmq -p 9324:9324 tsukada/elasticmq:0.15.3`

起動確認

% docker ps
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS              PORTS                    NAMES
cb1023027390        tsukada/elasticmq:0.15.3   "java -jar /elasticm…"   3 seconds ago       Up 2 seconds        0.0.0.0:9324->9324/tcp   elasticmq

起動成功。localhost の 9324 portとのマッピングも成功した。

使い方

キューの作成

aws sqs create-queue --queue-name test --endpoint-url http://localhost:9324
{
    "QueueUrl": "http://localhost:9324/queue/test"
}

ここで表示される`QueueUrl`が、メッセージの送受信などで必須情報となる。

メッセージ送信

作成したキューにメッセージを送信する。

`–queue-url` オプションが必要になる。ここではキューを作成した際に作られた`QueueUrl`を入力する。

aws sqs send-message --queue-url http://localhost:9324/queue/test --message-body 'tsukada hoge. Hello world' --endpoint-url http://localhost:9324

{
    "MD5OfMessageBody": "c5ec7b6e06ad8b6faf949efb02e2f406", 
    "MessageId": "83a36e5f-1d40-4da8-84eb-b37a8c864541"
}

送信が成功すると、メッセージ本文の MD5 ダイジェストとメッセージ ID が表示される。

メッセージを受信する

aws sqs receive-message --queue-url http://localhost:9324/queue/test --endpoint-url http://localhost:9324
{
    "Messages": [
        {
            "Body": "tsukada hoge. Hello world ", 
            "ReceiptHandle": "83a36e5f-1d40-4da8-84eb-b37a8c864541#58efa4b9-8fe9-4324-aded-08b72253be1c", 
            "MD5OfBody": "c5ec7b6e06ad8b6faf949efb02e2f406", 
            "MessageId": "83a36e5f-1d40-4da8-84eb-b37a8c864541"
        }
    ]
}

メッセージで送信された

tsukada hoge. Hello world

を確認できた。
ちなみに、このコマンドを複数回実行しても、毎回メッセージが表示されるわけではない。

SQSには可視性タイムアウトという考えがあり、デフォルトで1度キューを表示したら、30秒間は表示されない。

この仕組みで、重複してキューが実行されるのを防いでいる。

そのような仕様だと、「見えているキュー、見えてないキュー」の件数を確認したくなる。

見ているキュー、見えていないキューの件数を確認したい

 見えているキュー(キューから取得可能なメッセージのおおよその数)

`ApproximateNumberOfMessages` が見えている件数

aws sqs get-queue-attributes --endpoint-url http://localhost:9324 --queue-url http://localhost:9324/queue/test --attribute-names ApproximateNumberOfMessages
{
    "Attributes": {
        "ApproximateNumberOfMessages": "1"
    }
}

見えてないキュー(処理されたメッセージ)

`ApproximateNumberOfMessagesNotVisible`を `–attribute-names`に指定することで見えなくなっているキューの件数を表示することができる。

aws sqs get-queue-attributes --endpoint-url http://localhost:9324 --queue-url http://localhost:9324/queue/test --attribute-names ApproximateNumberOfMessagesNotVisible
{
    "Attributes": {
        "ApproximateNumberOfMessagesNotVisible": "0"
    }
}

これらのオプションについては公式ドキュメントで綺麗に整理されている。

https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-resources-required-process-messages.html

メッセージを削除する

不要になったメッセージは削除した方が良い。削除コマンドは以下の通り。

aws sqs delete-message  --endpoint-url http://localhost:9324 --queue-url http://localhost:9324/queue/test --receipt-handle "****"

`–receipt-handle` には、メッセージを受信した際に記載されている`ReceiptHandle`を指定する。

receive-message (メッセージを受信)した際、した際に確認できる ReceiptHandle はこのような感じに表示される。`.jq` コマンドなどを利用すれば簡単にシェル化できそうだ。

QueueUrlsを確認する

QueueUrlsを確認できるのはもちろんキュー作成時だけではなく、確認用のコマンドも用意されている。

aws sqs list-queues --endpoint-url http://localhost:9324
{
    "QueueUrls": [
        "http://localhost:9324/queue/test"
    ]
}

参考情報

https://qiita.com/tsukapah/items/0ba64ac734e885f6e8e8

https://qiita.com/tcsh/items/7781fe238df82fc030d2

参考情報

AWSについて体系的に学ぶことができるのでおすすめ。