SNS+SQSのファンアウトで疎結合アーキテクチャを作る【SAA頻出】
「注文が入ったら、在庫を減らし、メールを送り、分析基盤にも記録したい」。こうした1つのイベントを複数の処理に配るパターンをファンアウトと呼びます。AWS では SNS(配信)と SQS(キュー)を組み合わせるのが定番です。
なぜ SNS から直接 Lambda を呼ばずに SQS を挟むのか
SNS から各処理を直接呼ぶこともできますが、間に SQS を挟むと次の利点があります。
- バッファになる:注文が急増しても、メッセージはキューに溜まり、処理側は自分のペースで取り出せる
- 失敗に強い:処理に失敗したメッセージはキューに残り、再試行できる
- 独立してスケール:在庫処理が遅くても通知処理には影響しない
試験のコツ:問題文に「疎結合(decouple)」「急なスパイクに耐える」「メッセージを失わない」とあれば、SQS を挟む構成が正解候補です。
標準キューと FIFO キュー
| 標準キュー | FIFO キュー | |
|---|---|---|
| 順序 | ベストエフォート(入れ替わることがある) | 送信順を保証(メッセージグループ単位) |
| 重複 | まれに重複配信される(少なくとも1回) | 重複排除あり |
| スループット | ほぼ無制限 | 上限あり(高スループットモードで拡張可) |
ファンアウトで順序が必要な場合は、SNS FIFO トピック → SQS FIFO キューの組み合わせにします。
よくあるひっかけ:標準キューを使う場合、処理側は「同じメッセージが2回届いても大丈夫」なように冪等(べきとう)に作る必要があります。「二重課金を防ぎたい」なら FIFO か冪等な設計が答えです。
押さえておきたい SQS の設定
- 可視性タイムアウト:取り出されたメッセージが、他の受信者から見えなくなる時間。処理時間より短いと、処理中に別のワーカーがもう一度取り出してしまう
- デッドレターキュー(DLQ):何度処理しても失敗するメッセージを退避させるキュー。原因調査に使う
- ロングポーリング:受信待ちを最大20秒まで延ばし、空の応答(=無駄なAPI呼び出し)を減らす
- メッセージ保持期間:既定4日、最大14日
SNS → SQS で忘れがちな設定
SNS からキューにメッセージを届けるには、SQS 側のキューポリシーで「このトピックからの送信」を許可する必要があります。サンドボックスでこの構成を CloudFormation に書き出すと、サブスクリプションとキューポリシーがセットで生成されます。
また、配信先ごとにサブスクリプションフィルターポリシーを設定すると、「金額が1万円以上の注文だけ審査キューへ」のように、必要なメッセージだけを届けられます。
理解度チェック:ワーカーの処理に平均5分かかるのに、同じメッセージが何度も処理されてしまう。原因は?
可視性タイムアウトが処理時間(5分)より短いため。処理時間より長く設定します(Lambda をトリガーにする場合は、関数のタイムアウトの6倍程度が推奨)。
まとめ
- SNS で配り、SQS で受けるのがファンアウトの定番
- SQS を挟むとバッファ・再試行・独立スケールが手に入る
- 順序と重複排除が必要なら FIFO、標準キューなら冪等に