📩

Boto3 で SQS キューをポーリングしてメッセージを受信する方法

2021/04/17に公開

タイトルの通りです。
AWS SDK の Boto3 で SQS が保持しているキューをポーリングし、メッセージを表示させる方法を紹介します。

準備

権限の付与

EC2 で実行するにせよ、Lambda で実行するにせよ SQS メッセージの読み込みに必要な IAM ポリシー ()を割り当てておいてください。
(Lambda であれば AWSLambdaSQSQueueExecutionRole で OK です。)

権限の管理はアクセスキーよりも IAM ロールの割り当ての方が管理しやすいので、EC2 or Lambda に必要なポリシーを割り当てられた IAM ロールを紐付けてしておきましょう。
今回は EC2 で一時的に実行するので EC2PowerUserAccessRole で済ませてしまいます。

キューとメッセージの準備

事前に SQS キューを作っておきます。

URL 欄に記載されている値に対して Boto3 でアクセスしてメッセージを受信することになるので、この値をメモだけしておきます。

また、SQS にテスト用のメッセージキューを持たせるために [メッセージを送受信] ボタンを選択し、適当なメッセージをキューに入れていきます。

メッセージ入力画面でテキストを入力し、最後に [メッセージを送信] を選択します。

これでメッセージがキューに入りました。
実際、キューの一覧画面に戻るとメッセージが 1 件、キューに入っていることが分かります。
このメッセージを Boto3 で取り出してみましょう。

Boto3 での実装 (メッセージの受信)

receive_message_from_sqs.py というファイルを EC2 上に作成し、記述します。
boto3 等、必要なモジュールは pip でインストールしておきましょう。

import boto3

queue_url = "https://sqs.ap-northeast-1.amazonaws.com/XXXXXXXXXXX/test-sqs"
region = "ap-northeast-1"

sqs_client = boto3.client("sqs", region_name=region)
response = sqs_client.receive_message(QueueUrl=queue_url, MaxNumberOfMessages=1, VisibilityTimeout=60)

for res in response['Messages']:
  if 'Body' in res:
    print(res['Body'])

"XXXXXXXXXXXX" の箇所はお使いの AWS アカウント ID が当てはまっているはずです。

正常にメッセージを取り出せた時、出力結果は次のようになります。

$ python3 receive_message_from_sqs.py
キューに入れたテストメッセージ

設定したテストメッセージを取り出せました。

ちなみにこの時、もう一度キューの一覧画面をみてみると "利用可能なメッセージ" にあった数字 1 が "処理中のメッセージ" に移動していることが分かります。

Boto3 のコードの中で VisibilityTimeout=60 と設定しているので、この時間の間は一度呼び出したクライアント (今回は EC2) だけがメッセージを独占して扱えるようになっています。
時間がかかる処理を行っている間に他のクライアントが操作や読み取りをしてしまうことを防ぐための大事な仕組みであり、この仕組のおかげで疎なシステムを構築することが可能となります。

Discussion