本記事は以下ブログの内容を転記したものです。
以下ブログの方が見やすいと思います。気になる方はどうぞです。
はじめに
最近、仕事でSQSを使う機会があったのですが、デッドレターキューやSQSによるリトライ処理がイマイチ理解できていませんでした。
AWSの公式ドキュメントやブログ記事などを見てもあまり理解できなかったため、実際にサンプルアプリを作って検証しました。
実施内容(概要)
実施内容は以下です。
- LambdaにSQSでメッセージを送信する
- Lambdaはエラーとなるような処理とする
- 複数リトライ後、SQSのメッセージがデッドレターキューに入ることを確認する
- デッドレターキューに入ったメッセージを使って再処理できることを確認する
実施内容(詳細 - 設定)
IAM
一般的なユースケースからLambdaを選択し、次のステップ:アクセス権限を押します。
ポリシーとしてAmazonSQSFullAccessとCloudWatchLogsFullAccessを選択します。理由はそれぞれ以下です。選択後、次のステップ:タグを押します。
-
AmazonSQSFullAccess:LambdaがSQSメッセージを処理するため -
CloudWatchLogsFullAccess: LambdaがSQSメッセージ処理後にCouldWatch logsにログを出力するため
タグの設定はスキップし、次のステップ:確認を押します。
一通りの内容を確認します。また、ロール名は適当に付けてロールの作成を押します。
これでIAMの設定は完了です。
Lambda
次にLambdaで検証用の関数を作成します。
サンプルアプリの言語としてPythonを選択します。
アクセス権限は既存のロールを選択し、先ほど作成したロールを選択します。
コードは以下のコードを貼り付けて、必ずエラーとなるようにします。
import json
def lambda_handler(event, context):
msg = event['Records'][0]['body']
print(msg)
try:
a = 1 / 0
except:
raise Exception('ERROR!!')
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
以下でSQSの設定後に、トリガーを追加をクリックし、以下設定します。
- トリガーとしてSQSを選択
- SQSキュー:sample-message-queue
- バッチサイズ:1
- バッチウィンドウ:0
SQS
今回は以下2つのキューを作成します。
- sample-message-queue:上記Lambdaにメッセージを送信するキュー
- sample-message-queue-dlq:デッドレターキューを格納するキュー
それぞれ以下のように作成していきます。
デッドレターキューを格納するキュー
- タイプ:標準
- 名前:sample-message-queue-dlq
- 設定:デフォルト
- アクセスポリシー:デフォルト
Lambdaにメッセージを送信するキュー
- タイプ:標準
- 名前:sample-message-queue
- 設定:デフォルト
- アクセスポリシー:デフォルト
- デッドレターキュー:有効
- キューの選択:sample-message-queue-dlq
- 最大受信数:5:sample-message-queueが5回リトライ後、メッセージがsample-message-queue-dlq移動する
実施内容(詳細 - 検証)
検証1:リトライ後、SQSのメッセージがデッドレターキューに入ることを確認する
以下の手順でSQSでメッセージを送信してみます
- SQSで
sample-message-queueを選択し、メッセージを送受信をクリック - メッセージ本文に
testと入力する - 配信遅延時間:デフォルト(=0秒)とする
- メッセージを送信
すると、sample-message-queueで処理中のメッセージが1つあることがわかります。
数分後に、CloudWatchログを確認すると、最大受信数分だけLambdaがリトライ処理をしていることがわかります。
SQSをみると、sample-message-queue-dlqにメッセージが移動していることがわかります。
次に、以下手順により、先ほど送ったメッセージを取得できていることを確認できます。
-
sample-message-queue-dlqを開き、メッセージを送受信を押す -
メッセージをポーリングを押す - 先ほど送ったメッセージを取得し、
testと書かれたメッセージを確認できる
スクリーンショットを取得し忘れましたが、、上記手順で確認できるはずです。
検証2:デッドレターキューに入ったメッセージを使って再処理できることを確認する
検証1でデッドレターキューにメッセージが入り、中身を確認することができました。
次に、このメッセージを再度処理してみましょう。
以下手順でメッセージを再処理できます。
-
sample-message-queue-dlqを開き、DLQ再処理の開始を押す -
メッセージの送信先:再処理のためにカスタム送信先に移動を押す - 既存のキュー:
sample-message-queueを押す -
DLQ再処理を押す
上記により、先ほどsample-message-queue-dlqに入っていたメッセージが、sample-message-queueに移動していることがわかります。
再度CloudWatch logsをみると、最大受信数分だけLambdaがリトライ処理をしていることがわかります。
まとめ
今回はSQSのデッドレターキューを理解するために、SQS+Lambdaによりリトライ処理を実装してみました。
自分で手を動かして実装したことで、SQSについて理解が深まりました。
今後もAWSの他サービスやプログラミングに関する検証系のブログ記事を書いていこうと思います。
参考




