分散システム間のメッセージを安全にキューイングするフルマネージドメッセージキューサービス
Amazon SQS(Simple Queue Service)は、フルマネージドのメッセージキューサービスです。アプリケーション間でメッセージを非同期にやり取りすることで、サービス間を疎結合にできます。現実世界に例えると「郵便受け」のようなもので、送信者(プロデューサー)は受信者(コンシューマー)の状態を気にせずメッセージを投函でき、受信者は自分のペースで処理できます。
SQS には2つのキュータイプがあります。Standard キューは「少なくとも1回の配信」を保証し、ほぼ無制限のスループットを提供しますが、メッセージの順序は保証されません。FIFO キューは「正確に1回の処理」と「メッセージの順序保証」を提供しますが、秒間300メッセージ(バッチで3,000)の制限があります。SAA 試験では、ユースケースに応じてどちらを選ぶかが問われます。
SQS の主なユースケースは、マイクロサービス間の通信、非同期処理(注文処理、画像変換など)、ピーク負荷の平滑化(バッファリング)、ファンアウトパターン(SNS + SQS の組み合わせ)などです。メッセージの保持期間はデフォルト4日、最大14日で、メッセージサイズは最大256KBです。それ以上のデータを扱う場合は、Extended Client Library を使って S3 にデータを格納し、SQS にはポインタだけを送信します。
プロデューサーはメッセージをキューに送るアプリです。例えば Web サーバーが注文情報をキューに投入するケースが典型例です。SendMessage API でメッセージを送ったら、それで完了。コンシューマーの応答を待ちません(非同期通信)。送る側は受け取る側の状態を一切知らなくて OK です。
キューはメッセージを一時的に保持するバッファです。送る側が毎秒1000件送っても、受け取る側が毎秒100件しか処理できなくても、キューが溜めて吸収してくれます。セール時のアクセス急増でも、キューがあればシステムが落ちずに済みます。
コンシューマーはキューからメッセージを取り出して処理するアプリです。SQS はプル型なので、コンシューマーが自分から「メッセージある?」と取りに行きます(キューから自動で届くわけではない)。処理が終わったら 自分でメッセージを削除する必要があります。削除しないとメッセージがキューに戻って二重処理されます。
可視性タイムアウト(Visibility Timeout)は、コンシューマーがメッセージを受信してから、他のコンシューマーに見えなくなる期間です。デフォルトは30秒で、0秒から最大12時間まで設定できます。この間にコンシューマーがメッセージを処理し、DeleteMessage を呼び出す必要があります。
可視性タイムアウトが切れる前に処理が完了しない場合、メッセージはキューに戻り、別のコンシューマーが再度受信できるようになります。これは「二重処理」のリスクを意味するため、コンシューマーの処理は冪等(べきとう)であるべきです。つまり、同じメッセージを2回処理しても結果が変わらないように設計します。
処理に予想以上の時間がかかる場合は、ChangeMessageVisibility API で可視性タイムアウトを延長できます。逆に、処理が非常に速い場合はタイムアウトを短く設定して、失敗時のリカバリを高速化できます。適切なタイムアウト値は「平均処理時間の2~3倍」が目安です。
タイムアウト内に処理完了 → DeleteMessage → メッセージが完全に削除される。これが正常フローです。
タイムアウト切れ or 例外発生 → DeleteMessage が呼ばれない → メッセージがキューに復帰し、再処理される。receiveCount が増加する。
SQS のメッセージは自動では削除されません。コンシューマーが処理成功後に DeleteMessage API を明示的に呼び出す必要があります。これは「処理が本当に完了したことをコンシューマー自身が保証する」というSQSの設計哲学です。
DeleteMessage には ReceiptHandle が必要です。これは ReceiveMessage のレスポンスに含まれる一時的なトークンで、「このメッセージを受信したのは自分だ」という証明です。同じメッセージでも受信するたびに異なる ReceiptHandle が発行されるため、古い ReceiptHandle では削除できません。
メッセージの保持期間(MessageRetentionPeriod)を過ぎると、DeleteMessage が呼ばれなくてもメッセージは自動的に削除されます。デフォルトは4日(345,600秒)、最大14日(1,209,600秒)です。DLQ に移動したメッセージも同じ保持期間が適用されるため、調査が遅れるとメッセージが失われる可能性があります。
Dead Letter Queue(DLQ)は、処理に繰り返し失敗したメッセージの退避先となるキューです。メインキューにリドライブポリシーを設定し、maxReceiveCount を指定します。メッセージの受信回数がこの値に達すると、自動的にDLQに移動されます。
DLQ の重要な制約は、メインキューと同じタイプである必要があることです。Standard キューの DLQ は Standard、FIFO キューの DLQ は FIFO でなければなりません。また、DLQ はメインキューと同じ AWS アカウント・リージョンに作成する必要があります。
DLQ に溜まったメッセージは、CloudWatch アラーム(ApproximateNumberOfMessagesVisible メトリクス)で監視し、速やかに原因調査を行います。原因を修正した後は、AWS コンソールまたは StartMessageMoveTask API でメッセージを元のキューにリドライブ(再送)できます。DLQ がないと、毒メッセージ(poison message)がメインキューを詰まらせ続ける問題が発生します。
Short Polling(WaitTimeSeconds=0)は、キューにメッセージがなくても即座に空のレスポンスを返します。さらに、SQS の内部サーバーのサブセットだけをサンプリングするため、メッセージが存在しても取得できない場合があります(false empty response)。ポーリング間隔を短くすると大量の空リクエストが発生し、コストが増大します。
Long Polling(WaitTimeSeconds=1~20)は、メッセージが到着するかタイムアウトするまで待機します。SQS の全サーバーをクエリするため、false empty response が発生しません。空リクエストが大幅に減少し、コスト削減とレイテンシ改善を同時に実現できます。
Long Polling は、キューの設定(ReceiveMessageWaitTimeSeconds 属性)またはリクエスト単位(WaitTimeSeconds パラメータ)で有効化できます。ほぼ全てのユースケースで Long Polling が推奨され、AWS のベストプラクティスでもあります。SAA 試験では「SQS のコストを削減するには?」という問題で Long Polling が正解になることが頻出します。
| 比較項目 | Short Polling | Long Polling |
|---|---|---|
| 空レスポンス | 多い | 少ない |
| コスト | 高い | 低い |
| サーバークエリ | 一部のみ | 全サーバー |
| レイテンシ | 低い(即応答) | 低い(即配信) |

AWSリソースへのアクセスを安全に管理する認証・認可サービス

AWSリソースへのアクセスを安全に管理する認証・認可サービス

リレーショナルデータベースの構築・運用を自動化するマネージドサービス

リレーショナルデータベースの構築・運用を自動化するマネージドサービス

リレーショナルデータベースの構築・運用を自動化するマネージドサービス

リレーショナルデータベースの構築・運用を自動化するマネージドサービス