概要
この記事では、SNS と SQS と Lambda を使用したメッセージ基盤について紹介します。
アーキテクチャは下図の通りです。

大まかな処理の流れとしては以下の流れとなります。
- SNS でメッセージが発行される(失敗した場合はデッドレターキューに送る)
- SQS が Lambda にメッセージをキューイングする(失敗した場合はデッドレターキューに送る)
- Lambda がイベント起因で駆動する
アーキテクチャ図下部の、DLQ にメッセージが入ったら Slack に通知する箇所については以下の記事で紹介します。
- DLQ にキューが入ったら Slack へアラートを送信する
まずは環境を構築します。
この記事で作成する環境は下図の通りです。
× N個
としている箇所については、今回は 3 個にしています。

上記 terraform を apply します。
現時点ではまだ ECR にイメージが存在しないため、Lambda の作成はエラーとなります。そのため、ECR にイメージを push した後で再度 terraform apply する必要があります。
Lambda 用 Docker イメージ作成
次に Lambda 用 Docker イメージを ECR へ push します。
lambda.py
今回はメッセージを確認できれば十分なので、下記のような簡単な関数を使用します。
Dockerfile
Dockerfile は下記です。Docker イメージを作成して ECR へ push します。

備考
ECR へイメージを push したら、再度 terraform apply を実施して Lambda を作成します。
メッセージ発行
環境が整ったので、SNS に対してメッセージを発行します。
今回は AWS SDK を使用してメッセージを発行します。
上記 python を使用してメッセージを発行してみると、全ての Lambda が実行され、メッセージも渡されていることが確認できます。

デッドレターキューを試す
SNS→SQS→Lambda の順でメッセージを渡せることは確認できました。
次は、意図的に Lambda の処理を失敗させて、デッドレターキューに失敗したキューを格納してみます。
lambda.py
Lambda 関数を下記のように修正して、エラーが発生するようにします。
実行してみる
再度、AWS SDK を使用して SNS にメッセージを発行してみると、全ての Lamdba はそれぞれ 3 回実行され、その後デッドレターキューに格納されていることが分かります。
リトライ回数はaws_sqs_queue.main
のmaxReceiveCount
で定義しています。

まとめ
この記事では、SNS と SQS と Lambda を使用したメッセージ基盤の構築について紹介しました。メッセージを複数の処理に渡したい、かつメッセージの発付に失敗した際も確認できるようにしたい場合に有効な構成です。
参考

備考
Hakky ではエンジニアを募集中です!まずは話してみたいなどでも構いませんので、ぜひお気軽に採用ページからお問い合わせくださいませ。
