1. ホーム
  2. amazon-web-services

SqSメッセージがキューにインフライトしたままになることがある理由

2023-12-15 17:21:54

疑問点

Amazon SQSのキューを非常にシンプルな方法で使っています。通常、メッセージは書き込まれ、すぐに表示され、読み込まれます。時折、メッセージが書き込まれ、数分間キューにIn-Flight(Not Visible)されたままになることがあります。コンソールから見ることができます。Receive-message-wait timeは0、Default Visibilityは5秒です。これは数分間、あるいは新しいメッセージが書き込まれ、それが何らかの形で解放されるまで、その状態を維持します。数秒の遅れは大丈夫ですが、60秒以上はダメです。

8 つのリーダー スレッドがあり、常に長いポーリングを行っています。

編集 : はっきりさせるために、コンシューマの読み込みはどれもまったくメッセージを返さず、コンソールが開いているかどうかに関係なく起こります。このシナリオでは、1 つのメッセージだけが関与し、それはコンシューマーからは見えないキューに座っています。

他にこの動作を見た人はいますか、また、それを改善するために何ができるでしょうか。

私が使用しているjavaのsdkはこちらです。

<dependency>
  <groupId>com.amazonaws</groupId>
  <artifactId>aws-java-sdk</artifactId>
  <version>1.5.2</version>
</dependency>     

以下は、読み込みを行うコードです(max=10,maxwait=0の起動時設定)。

void read(MessageConsumer consumer) {

  List<Message> messages = read(max, maxWait);

  for (Message message : messages) {
    if (tryConsume(consumer, message)) {
      delete(message.getReceiptHandle());
    }
  }
}

private List<Message> read(int max, int maxWait) {

  AmazonSQS sqs = getClient();
  ReceiveMessageRequest rq = new ReceiveMessageRequest(queueUrl);
  rq.setMaxNumberOfMessages(max);
  rq.setWaitTimeSeconds(maxWait);
  List<Message> messages = sqs.receiveMessage(rq).getMessages();

  if (messages.size() > 0) {
    LOG.info("read {} messages from SQS queue",messages.size());
  }

  return messages;
}

この現象が発生しているとき、"read .." のログ行は決して表示されず、そのために私はコンソールに入り、メッセージがそこにあるかどうかを確認することになります。

どのように解決するのですか?

あなたが見ているものを間違って解釈しているようです。

メッセージ "in flight" は配信待ちではなく、すでに配信されているがコンシューマによってさらに処理されていないメッセージです。

メッセージは、クライアントに送信されたがまだ削除されていない場合、またはまだ可視性ウィンドウの終わりに達していない場合、飛行中であるとみなされます。

- https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-available-cloudwatch-metrics.html

コンシューマがメッセージを受信したとき、ある時点でそのメッセージを削除するか、あるいは タイムアウトを増加させる を増加させるリクエストを送信しなければなりません。 さもなければ、タイムアウトが過ぎると、メッセージは再び見えるようになります。 可視化タイムアウトは、コンシューマがこれらの処理のいずれかを実行しなければならないまでの時間です。

しかし、その「何か」には、コンソール自体も含まれます。コンソールで「メッセージの表示/削除」を選択したときに表示されるポップアップに注意しましょう (ただし、「二度と表示しない」チェックボックスをオンにした場合を除きます)。

コンソールに表示されたメッセージは、コンソールがメッセージのポーリングを停止するまで、他のアプリケーションで利用することはできません。

コンソールに表示されるメッセージは、"View/Delete Messages"画面からキューを観察している間、"in flight"です。

明らかな意味をなさない部分は、デフォルトの可視性タイムアウトがわずか 5 秒で、コード内の何もそのタイムアウトを増やしていない場合、メッセージが数分間飛行中であることです...しかし... しかし、...これは、消費者がメッセージを適切に廃棄しないためにタイムアウトしてすぐに再送信され、メッセージの単一のインスタンスが飛行中に残っているような印象を与えることによって、ほぼ完全に説明することができます。