0

私は呼び出しています:

GetResponse response = channel.basicGet("some.queue", false); // no auto-ack
....
channel.basicAck(deliveryTag, ...);

ただし、を呼び出すbasicGetと、キュー内のメッセージは「未確認」ではなく「準備完了」のままになります。私はそれらを未確認のままにしたいので、basic.ackそれらを(したがってキューから破棄する)、またはbasic.nackそれらのいずれかを行うことができます

4

2 に答える 2

4

ack の遅延を模倣するために次のことを行っています。

消費時

  1. 初期キューからメッセージを取得 (消費) します。
  2. 「PendingAck_123456」キューを作成します。
    123456 は、メッセージの一意の ID です。
    次のプロパティを設定します
    • x-message-ttl (タイムアウト後に再キューイングするため)
    • x-expires (一時キューが確実に削除されるようにするため)
    • x-dead-letter-exchangeおよびx-deal-letter-routing-key使用して、TTL の期限切れ時に最初の Queue に再キューイングします。
  3. メッセージ Pending ack をこの「PendingAck_123456」キューにパブリッシュします
  4. メッセージを確認して初期キューから削除します

承認時

  1. メッセージ ID からキュー名を計算し、「PendingAck_123456」キューから取得する
  2. 確認します ( に電話する必要はありません.getBody())。
    これにより、この保留中のキューからそれが削除され、TTL が再キューイングするのを防ぎます

備考

  • 1つのメッセージのみのキュー..そのようなキューがたくさんある場合、それは問題ですか?
  • 再キューイングされたメッセージは、キューの出力側ではなく、キューの入力側で送信されます (実際の ack のように)。メッセージの順序に影響があります。
  • メッセージは、アプリケーションによって保留中のキューにコピーされます。これは、全体的なパフォーマンスに影響を与える可能性のある追加の手順です。
  • Nack/Reject を模倣するには、メッセージを Initial Queue にコピーし、PendingAck キューから Ack します。デフォルトでは、TTL がそれを行います (後で)。
于 2014-01-13T08:39:43.630 に答える
2

ackの直後に行うgetと正常に動作します。しかし、私の場合、それらはリクエストによって分離されました。また、Spring のテンプレートは、実行ごとにチャネルと接続を閉じます。したがって、次の 3 つのオプションがあります。

  • アプリケーションの存続期間全体を通じて、1 つのチャネルと接続を開いたままにします。
  • 同じチャネルを保存して再利用するために、ある種の会話スコープ (または最悪の場合: セッションを使用) を用意します。
  • 要求ごとに 1 つのチャネルを使用し、すぐに受信を確認し、メッセージをメモリに保存します。

前の2つのケースでは、春のものではできませんRabbitTemplate

于 2011-10-24T11:38:11.233 に答える