モチベーション
- 業務で最近良く使用している非同期の王道パターンなのでついでに深い知識を得たいため
- この人にSQS + Lambdaを聞けば安心だよねという状態に持っていきチームに頼られるようになりたい
前提レベル
- 業務ですでに基盤に乗っているSQSとLambdaを触ったことがあるレベル
- オライリーラーニングのAWS Sandboxで軽くSQS + Lambdaの環境を構築したレベル
学習につかうもの
基本的には公式ドキュメントを参照しつつ、Chat GPTとかに投げていく
https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html
利点
1. セキュリティ
- 誰がメッセージを送受信できるかを制御できる
- アクセス制御(IAMポリシー)
- 例えば、EC2 から SQS にメッセージを送れるけど、外部ユーザーは送れないように設定可能。
- アクセス制御(IAMポリシー)
- メッセージを暗号化して安全に保管できる
- 暗号化(SSE:Server-Side Encryption)
- 例えば、ユーザーの個人情報(名前、住所など)をメッセージに含める場合、暗号化して第三者が内容を見られないようにできる。
- 暗号化(SSE:Server-Side Encryption)
2. 耐久性
- メッセージは複数のサーバーに保存されるので、データが消えにくい
- サーバーが1台ダウンしても、別のサーバーでメッセージを保持
- 例えば、EC2 インスタンスが処理中に落ちても、メッセージは SQS 上に残るので、別のインスタンスが処理を引き継げる。
- サーバーが1台ダウンしても、別のサーバーでメッセージを保持
3. 可用性
- SQS は冗長化されたインフラを使っているので、落ちにくい
- 複数のサーバーがメッセージの送受信を支えるので、AWS 側で障害が発生しても問題が起こりにくい。
- 大量のメッセージを同時に送受信できる
- 例えば、数百人のユーザーが Web アプリで注文を送った場合、すべてのメッセージが SQS に保存され、サーバーが処理できるようになる。
4. スケーラビリティ
- SQS は負荷が増えても自動でスケールするので、事前にサーバーを増やす必要がない
- 例えば、ブラックフライデーのセールで注文が急増しても、SQS はメッセージを受け取る処理を自動的にスケールするので、処理遅延が起こりにくい。
5. 信頼性
- メッセージが処理されている間、他のコンシューマが同じメッセージを処理しないようにロックされる
- 例えば、ECサイトで「購入処理」のメッセージを SQS に送ったとき、処理中のメッセージは他のサーバーが誤って受け取らないようにロックされる。(可視性タイムアウト(Visibility Timeout))
6. カスタマイズ
- 遅延メッセージを設定(例:「注文確定後 10 秒後に通知を送る」)
- メッセージを Amazon S3 や DynamoDB に保存してリンクを SQS に送れる
- 256KB を超えるメッセージを S3 に保存し、そのURLを SQS に保存(例:「大きなデータの処理をスムーズに行う」)
仕組み
分散メッセージングシステム
- 非同期でシステム間のデータ転送を行うための仕組み
- 3つの主要コンポーネント で構成
1. 分散システムのコンポーネント
- プロデューサー(Producer): メッセージをキューに送信するシステム(例: Webアプリ、マイクロサービス)。
- コンシューマー(Consumer): メッセージをキューから受信して処理するシステム(例: Lambda関数、EC2インスタンス)。
2. キュー(Queue)
- メッセージを一時的に保存する場所。
- Amazon SQS サーバーに分散配置され、冗長化 されているため、耐障害性が高い
3. メッセージ(Message)
- プロデューサーが送信し、コンシューマーが処理するデータ。
- SQSの複数のサーバーに冗長的に保存 されるため、システム障害時もメッセージが失われにくい。
メッセージのライフサイクル
ステップ | アクション | 説明 |
---|---|---|
1. 送信 | SendMessage |
プロデューサーが SQS にメッセージを送信 |
2. 冗長保存 | SQS サーバー | メッセージは Amazon SQS の複数のサーバーに冗長保存 |
3. 受信 & 可視性タイムアウト開始 | ReceiveMessage |
コンシューマーがメッセージを取得し、一定時間他のコンシューマーから見えなくなる(可視性タイムアウト) |
4. 処理成功 → 削除 | DeleteMessage |
コンシューマーが処理成功時、SQS からメッセージを削除 |
5. 処理失敗 → 再試行 | 可視性タイムアウト後に再取得 | 処理失敗すると、可視性タイムアウト終了後に再取得可能 |
6. リトライ回数超過 |
maxReceiveCount (例: 5) |
指定回数のリトライ後、デッドレターキュー(DLQ)に移動 |
7. 保持期間超過 | MessageRetentionPeriod |
最大 14 日間メッセージが保持され、超過すると自動削除 |
具体例で書いてみた