Amazon Simple Queue Service
開発者ガイド

Amazon SQS メッセージの操作

次のガイドラインは、Amazon SQS を使用して、効率的にメッセージを処理するのに役立ちます。

タイムリーな方法でのメッセージの処理

可視性タイムアウトの設定は、アプリケーションがメッセージを処理し、削除するのにかかる時間によって異なります。たとえば、アプリケーションでメッセージを処理するには 10 秒必要だが、可視性タイムアウトを 15 分に設定した場合、前のメッセージ処理に失敗すると、再度処理されるまでに長時間待つ必要があります。または、アプリケーションでメッセージを処理するには 10 秒必要だが、可視性タイムアウトを 2 秒に設定した場合は、元のコンシューマーがメッセージを処理している間に別のコンシューマーより重複メッセージが送信されます。

メッセージの処理に十分な時間があることを確認するには、次のいずれかの方法を使用します。

  • メッセージの処理にかかる時間がわかっている (または合理的に見積もることができる) 場合は、メッセージの可視性タイムアウトを、メッセージの処理と削除にかかる最大時間に拡張します。詳細については、可視性タイムアウトの設定およびメッセージの可視性タイムアウトの変更を参照してください。

  • メッセージの処理にかかる時間がわからない場合は、コンシューマープロセスのハートビートを作成します。初期の可視性タイムアウト (たとえば 2 分) を指定し、(コンシューマーがメッセージを処理し続けている限り) 可視性タイムアウトの毎秒 2 分ずつ延長します。

注記

12 時間以上に可視性タイムアウトを拡張する必要がある場合は、AWS Step Functions の使用を検討してください。

リクエストエラーの処理

リクエストのエラーを処理するには、次の方法のいずれかを使用します。

  • AWS SDK を使用している場合、既にある自動的な再試行およびバックオフロジックを活用できます。詳細については、アマゾン ウェブ サービス全般のリファレンス の「AWS でのエラーの再試行とエクスポネンシャルバックオフ」を参照してください。

  • 再試行とバックオフに AWS SDK の機能を使用しない場合は、Amazon SQS からメッセージ、タイムアウト、またはエラーメッセージが受信されなかった後で、一時停止 (たとえば、200 ms) してから、ReceiveMessage アクションを再試行します。同じ結果が得られる ReceiveMessage をそれ以降に使用するには、それよりも長い一時停止 (たとえば、400 ms) を許可します。

ロングポーリングのセットアップ

ロングポーリングは、空のレスポンス (ReceiveMessage リクエストに対して使用できるメッセージがない場合) と、偽の空のレスポンス (メッセージが利用できるがレスポンスに含まれていない場合) の数を削減することで、Amazon SQS の使用コストを削減するために役立ちます。詳細については、「Amazon SQS ロングポーリング」を参照してください。

最適なメッセージ処理を行うには、次の方法を使用します。

  • ほとんどの場合、ReceiveMessage 待機時間を 20 秒に設定します。アプリケーションの設定時間として 20 秒が長すぎる場合は、ReceiveMessage 待機時間の値を小さくします (最小 1 秒)。Amazon SQS へのアクセスに AWS SDK を使用しない場合、または AWS SDK に短い待機時間を設定する場合は、長いリクエストを許可するように、またはロングポーリングに短い待機時間を使用するように Amazon SQS クライアントを変更する必要がある場合があります。

  • 複数のキューにロングポーリングを実装する場合は、すべてのキューに単一スレッドを使用せずに、キューごとに 1 つのスレッドを使用します。キューごとに 1 つのスレッドを使用した場合は、メッセージが使用可能になると、アプリケーションはキューごとにメッセージを処理できるのに対し、複数のキューを単一スレッドでポーリングすると、使用可能なメッセージがないキューを待機 (最大 20 秒) している間、アプリケーションは他のキューで使用可能なメッセージを処理できません。

問題のあるメッセージのキャプチャ

処理できないすべてのメッセージをキャプチャし、CloudWatch メトリクスの正確さを確保するには、デッドレターキューを設定します。

  • Redrive ポリシーは、ソースキューがメッセージの処理の失敗を指定回数繰り返した後に、デッドレターキューにメッセージをリダイレクトします。

  • デッドレターキューを使用するとメッセージ数が減少し、ポイズンピルメッセージ (受信されたが処理できないメッセージ) が発生する可能性が低下します。

  • キューにポイズンピルメッセージを含めると、ポイズンピルメッセージの誤った経過期間を指定することで、ApproximateAgeOfOldestMessage CloudWatch メトリクスが正しくなくなる可能性があります。デッドレターキューを設定すると、このメトリクスを使用する場合の誤ったアラームの回避に役立ちます。

デッドレターキューの保持の設定

メッセージの有効期限は、常に元のキュー追加のタイムスタンプに基づいています。メッセージが dead-letter queue に移動されると、キュー追加のタイムスタンプは変更されません。たとえば、メッセージがデッドレターキューに移動される前に元のキューに 1 日を費やし、デッドレターキューの保存期間が 4 日に設定されている場合、メッセージは 3 日後にデッドレターキューから削除されます。したがって、デッドレターキューの保持期間を元のキューの保持期間よりも長く設定することが、常にベストプラクティスとなります。

メッセージ処理の不整合の回避

スタンダード キューによる整合性のないメッセージ処理を回避するため、デッドレターキューの設定時に最大受信数を 1 に設定することは避けてください。

重要

一部の予期しないシナリオによっては、最大受信数を 1 に設定した場合、ReceiveMessage 呼び出しが失敗すると、メッセージが受信されることなくデッドレターキューに移動される可能性があります。

リクエストと応答システムの実装

リクエストと応答またはリモートプロシージャ呼び出し (RPC) システムを実装するときは、次のベストプラクティスに留意してください。

  • メッセージごとに返信キューを作成しない。代わりに、起動時にプロデューサーごとに返信キューを作成し、相関 ID メッセージ属性を使用して返信をリクエストにマッピングします。

  • プロデューサーで返信キューを共有しない。共有した場合、プロデューサーは他のプロデューサー向けの応答メッセージを受信する可能性があります。