–wait-time-secondsとは

aws sqs receive-message コマンドはデフォルトでShort Pollingを使用する。Short Pollingではキューにメッセージがなくても即座に空のレスポンスを返すため、ポーリングを繰り返すと無駄なAPIコールが発生する。

--wait-time-seconds オプションを指定するとLong Pollingになり、メッセージが到達するまで最大で指定した秒数待ってからレスポンスを返す。

$ aws sqs receive-message \
  --queue-url https://sqs.ap-northeast-1.amazonaws.com/[account-id]/[queue-name] \
  --wait-time-seconds 20

指定できる最大値は20秒。

Long Polling のメリット

  • メッセージがない場合の空レスポンスが減り、APIコール数を削減できる
  • Short PollingではSQSの分散サーバーの一部しか確認しないため、メッセージが存在しても空レスポンスを返すことがある(false empty response)。Long Pollingはすべてのサーバーを確認するためこの問題が解消される
  • APIコール数の削減によりコストが下がる
  • メッセージ到達をリアルタイムに近い形で検出できる

FIFO キューで複数コンシューマーを使う場合

FIFOキューはメッセージグループID(送信時に --message-group-id で指定)ごとに順序を保証する。同じグループIDのメッセージは、先行するメッセージが削除されるかvisibility timeoutが切れるまで後続のメッセージを取得できない。

複数のコンシューマーが同時にポーリングしている場合、1つ目のコンシューマーがメッセージを取得して削除するまでの間、後続の同じグループIDのメッセージは取得できない状態になる。この状態で --wait-time-seconds を指定せずShort Pollingで即座にリトライし続けると、空レスポンスが大量に発生する。

--wait-time-seconds を指定すると、前のメッセージが削除されてキューに次のメッセージが取得可能になるまで待機するため、無駄なポーリングを抑えられる。

$ aws sqs receive-message \
  --queue-url https://sqs.ap-northeast-1.amazonaws.com/[account-id]/[queue-name].fifo \
  --wait-time-seconds 20 \
  --max-number-of-messages 1

SQSキュー側の設定

キューの属性 ReceiveMessageWaitTimeSeconds を設定すると、コマンドオプションを省略してもLong Pollingがデフォルトになる。

$ aws sqs set-queue-attributes \
  --queue-url https://sqs.ap-northeast-1.amazonaws.com/[account-id]/[queue-name] \
  --attributes ReceiveMessageWaitTimeSeconds=20

現在の設定を確認するには get-queue-attributes コマンドを使う。

$ aws sqs get-queue-attributes \
  --queue-url https://sqs.ap-northeast-1.amazonaws.com/[account-id]/[queue-name] \
  --attribute-names ReceiveMessageWaitTimeSeconds