メインコンテンツまでスキップ

Amazon Simple Queue Service

Overview

Amazon SQSは、フルマネージド型のメッセージキューイングサービス。
Amazon SQSを使うと、キューにメッセージを保存したり、キューからメッセージを取り出して処理ができる。
この仕組みを使うことで、疎結合なシステム間連携を実現できる。
メッセージをキューに格納している送信側のアプリケーションをプロデューサー、メッセージ受信側のアプリケーションをコンシューマーと呼ぶ。

  • 送信側のアプリケーション
    • プロデューサー
  • 受信側のアプリケーション
    • コンシューマー

Amazon SQSの特徴

Amazon SQSには次のような特徴がある。

疎結合による耐障害性の向上

メッセージキューイングをシステムに導入すると、アプリケーションコンポーネントが切り離される。
したがって実行や失敗は個別のものとなり、システムの全体的な耐障害性が向上する。

伸縮自在に自動スケーリング可能

メッセージキューイングにフルマネージド型サービスであるAmazon SQSを使用すると、自動的にスケールされるため、運用管理のコストを減らすことができる。

Amazon SQS側でのメッセージの暗号化(SSE)をサポート

Amazon SQS側での暗号化(SSE)をサポートしており、各メッセージの本文に機密情報を含んでいても安全にやり取りできる。

高い可用性を維持できる

キューに保存されたメッセージは単一のリージョンの複数のAZで冗長構成にて配置される。
そのため、失われる心配がなく、設定された保持期間内であればいつでも使用できる。

処理できなかったメッセージの蓄積を防ぐことができる

メッセージが正常に処理されなかった場合に、そのメッセージがデッドレターキューという場所に移動するように設定できる。 処理不可能なメッセージを分離することで、メッセージの滞留を防ぐことができる。

2つのキュータイプが利用できる

アプリケーションの要件に合わせて、標準キューとFIFOキューの2つのタイプから選択し、使用できる。

2つのポーリング方式を利用できる

Amazon SQSではポーリングを行う方式として、アプリケーションの要件に合わせて、ショートポーリングとロングポーリングの2つの方式から選択できる。

  • ショートポーリング
    • 受信側がメッセージ問い合わせをしてキューが空だった場合、すぐに空のメッセージが返送される
  • ロングポーリング
    • 受信側が問い合わせをしてキューが空だった場合、受信待機時間(1秒から20秒)を設定することでその時間分SQSが待機してから応答が返却される。

可視性タイムアウト

可視性タイムアウト機能を使用することで、受信側がAmazon SQSからメッセージを受信した場合、他の受信者にそのメッセージを一定期間(30秒から12時間)見せないことで、処理の重複を防ぐことができる。
たとえば、複数のコンシューマーが同時に同じメッセージを取得しないように、一度取得されたメッセージは可視性タイムアウトが経過するまで、他のコンシューマーから取得できなくする。
また一度失敗した処理のリトライ時にも可視性タイムアウトは有効。
たとえば、コンシューマー側のシステム障害などでメッセージの処理が失敗した場合、可視性タイムアウト経過後に別のコンシューマーが同じメッセージを処理する。

Amazon SQSの制約事項

Amazon SQSには次のような制約事項がある。

メッセージ上限

Amazon SQSで扱えるメッセージ数は無制限だが、1メッセージあたりの上限は256KBと決められている。
256KBを超える場合は、拡張クライアントライブラリを使用してS3に保存可能だが、上限は2GBとなっている。

メッセージ保持期間

メッセージの保持期間は、デフォルトで4日間となっており、60秒から14日間までの範囲で任意の値に設定が可能。
保持期間を過ぎると、自動的に削除される。

Amazon SQS クォーター

SQSの標準キューは1秒あたり無制限のAPI実行をサポートしている。
しかし他に考慮する必要があるとすれば、AWSアカウントごとにリージョンの同時実行数が設定されているため、設定を見直す必要などもある。
※上記を言い換えると、どんなに大規模な領収書の作成依頼メッセージが同時に発生しても、メッセージを保存できることを意味している。

SQSをLambdaに連結した場合のエラーハンドリング

Amazon SQSとAWS Lambdaを連携する場合、基本的にはAWS Lambdaの処理が正常終了したときにAmazonSQSキューから該当するメッセージが消えるしくみになっている。
逆に、AWS Lambdaの処理が異常終了した場合はどうなるのでしょうか。AWS Lambdaによって「他のクライアントから取得できない状態」にされた(受信ハンドルを取得したと言い換えることもできます)メッセージはそのままになってしまいます。
しかし、可視性タイムアウトという設定があるため、その秒数が経過した場合はメッセージの処理に何かしらの異常が発生したと判断し、自動的に「他のクライアントから取得できない状態」が解除されます。
言い換えると、異常終了になった場合は、AmazonSQSキューのメッセージ保管期間に達するまで前述の状態と解除を何度も繰り返すことになるため、開発者はAmazonSQS固有の障害対応をする必要はなく、なるべく早くプログラムを修正しAWSLambda関数をデプロイするだけです。

DLQ(Dead Letter Queue)

Amazon SQSキューのメッセージが指定回数処理されたらDLQとして使う別のAmazon SQSキューにメッセージを移動できる機能。
名前にDead Letterとあるとおり、誤ったメッセージを溜めておく「退避キュー」のようなイメージ。

冪等性の考慮

何らかしらのミスでキューに同じメッセージが2つ溜まってしまい、後続のメッセージに2つ渡されることがある。
そのためアプリケーション側で担保を取らないといけない。何らかのIDなどを付与してあげる。