AWSではマイクロサービス間の連携や非同期処理にSQS(キュー)とLambda(サーバーレス実行)を組み合わせることがよくあります。本記事ではSQSのポーリング、SNSとSQSの連携、Lambdaによる処理と失敗時の再試行(リトライ)をデッドレターキュー(DLQ)で実現する構成を解説します。
基本構成
- SNSトピック - サービス間でイベントを公開する場所。
- SQSキュー - SNSからの通知を受け取るキュー。標準キューを想定。
- Lambda関数 - SQSからメッセージを受け取り処理を行う。
- DLQ(Dead Letter Queue) - Lambdaの処理に失敗したメッセージを退避させるキュー。
SNSからSQSへのサブスクリプションを設定しておくことで、サービス側はSNSにメッセージを発行するだけで良くなります。
全体アーキテクチャ図
ポーリングの仕組み
SQSはメッセージを受信するためにポーリングが必要です。LambdaとSQSを統合すると、LambdaがSQSをポーリングして新しいメッセージを取得します。ポーリング間隔や並列数は設定で調整可能です。SQSにメッセージが到着するとLambdaが自動的に起動され、メッセージ内容を引数として処理を実行します。
ポーリングとメッセージ処理のフロー
リトライ戦略
Lambdaによる処理が失敗した場合、SQSの再試行ポリシーによってメッセージを再度受信できます。一定回数(例: 最大3回)までリトライし、それでも成功しなければDLQにメッセージを移動させます。DLQに退避されたメッセージは後続のバッチ処理や手動確認などで対応します。これにより、エラーを抱えたメッセージでも他のメッセージ処理を阻害しません。
リトライとDLQへの移動フロー
可視性タイムアウト
SQSでは"可視性タイムアウト"を使って、メッセージ取得後の削除までの間に他のコンシューマから見えなくすることができます。処理が成功したらメッセージを削除、失敗したら削除せずにタイムアウト後に再配信されます。これと最大受信回数(MaxReceiveCount)の組み合わせでリトライ制御を実現します。
可視性タイムアウトのタイムライン
SNS + SQS構成の利点
- 疎結合: SNSトピックを介することで、プロデューサとコンシューマ間の依存度を下げられます。
- 複数サブスクライバ: 1つのSNSトピックから複数のSQSキューへ通知できるため、異なる処理を並行して実行できます。
- 耐障害性: SQSはサービスダウン時でもメッセージを保持するため、再開後に処理を継続できます。
設定パラメータの例
| パラメータ | 推奨値 | 説明 |
|---|---|---|
| 可視性タイムアウト | 30秒〜5分 | Lambda関数の最大実行時間より長く設定 |
| MaxReceiveCount | 3〜5 | リトライ回数の上限 |
| メッセージ保持期間 | 4日(デフォルト) | SQSでメッセージを保持する最大期間 |
| DLQメッセージ保持期間 | 14日 | エラー分析のため長めに設定 |
まとめ
SQSとLambdaを組み合わせ、DLQを用意することで、AWS上で堅牢なメッセージ処理およびリトライ機構を簡単に構築できます。さらにSNSを利用すれば、イベント駆動アーキテクチャを実現しつつ、異なるコンシューマを柔軟に追加できます。
この構成を活用することで、エラー処理やスケーリングを気にせずに非同期処理を安心して任せられる環境を構築可能です。