コンシューマーがメッセージを取得した後、コンシューマー/ワーカーはいくつかの検証を行ってからWebサービスを呼び出します。このフェーズでは、エラーが発生した場合や検証が失敗した場合、最初に消費されたキューにメッセージを戻す必要があります。
RabbitMQのドキュメントを読みました。しかし、リジェクト、ナック、キャンセルの各メソッドの違いについて混乱しています。
短い答え:
特定のメッセージを再キューするには、multiple
フラグをfalseに設定して、basic.reject
またはbasic.nack
の両方を選択できます。
basic.consume
呼び出しは、メッセージ確認応答を使用しており、特定の時間にコンシューマーに未確認のメッセージがあり、コンシューマーが確認応答せずに終了した場合、メッセージが再配信されることもあります。
basic.recover
は、特定のチャネルですべての未確認メッセージを再配信します。
長答:
basic.reject
および basic.nack
は両方とも同じ目的に使用されます-特定のコンシューマーが処理できないメッセージをドロップまたはリキューします(特定の時点で、特定の条件下またはまったく)。それらの主な違いは、basic.nack
はバルクメッセージ処理をサポートするのに対し、basic.reject
はサポートしないことです。
負の謝辞 公式RabbitMQ Webサイトの記事で説明されているこの違い:
AMQP仕様では、クライアントが個々の配信されたメッセージを拒否し、ブローカーにメッセージを破棄するか、キューに再配置するよう指示する
basic.reject
メソッドを定義しています。残念ながら、basic.reject
は、否定的なメッセージの一括確認をサポートしていません。これを解決するために、RabbitMQは
basic.nack
のすべての機能を提供するbasic.reject
メソッドをサポートしていますが、メッセージの一括処理も可能です 。メッセージを一括して拒否するには、クライアントは
basic.nack
メソッドのmultiple
フラグをtrue
に設定します。その後、ブローカは、delivery_tag
メソッドのbasic.nack
フィールドで指定されたメッセージを含む、確認されていない配信済みメッセージをすべて拒否します。この点で、basic.nack
はbasic.ack
の一括確認応答セマンティクスを補完します。
basic.nack
メソッドはRabbitMQ固有の拡張機能であり、basic.reject
メソッドはAMQP 0.9.1仕様の一部であることに注意してください。
basic.cancel
メソッドについては、クライアントがメッセージの消費を停止することをサーバーに通知するために使用されていました。クライアントはbasic.cancel
メソッドとcancel-ok
応答の受信の間にある任意のメッセージ番号を受信する場合があることに注意してください。メッセージ確認がクライアントによって使用され、確認されていないメッセージがある場合、それらは最初に消費されたキューに戻されます。
basic.recover
RabbitMQにはいくつかの制限があります:it- basic.recover with requeue = false - basic.recover synchronicity
正誤表に加えて、 RabbitMQ仕様に準拠basic.recover
には部分的なサポートがあります(requeue = falseによるリカバリはサポートされていません)。
basic.consume
:に関する注意
basic.consume
auto-ack(noack=false
)なしで開始され、いくつかの保留中のメッセージが確認されていない場合、コンシューマがキャンセルされる(ダイ、致命的なエラー、例外など) )保留中のメッセージは再配信されます。技術的には、保留中のメッセージは、消費者がそれらを解放する(ack/nack/reject/recover)まで処理されません(配信不能であっても)。その後のみ処理されます(例:デッドレター)。
たとえば、元々5つのメッセージを連続して投稿するとします。
Queue(main) (tail) { [4] [3] [2] [1] [0] } (head)
そして、それらのうち3つを消費しますが、それらを確認してから、消費者をキャンセルします。この状況になります。
Queue(main) (tail) { [4] [3] [2*] [1*] [0*] } (head)
ここで、スター(*
)は、redelivered
フラグがtrue
に設定されていることに注意します。
送達不能の交換セットと送達不能メッセージのキューの状況があると仮定します
Exchange(e-main) Exchange(e-dead)
Queue(main){x-dead-letter-exchange: "e-dead"} Queue(dead)
そして、expire
プロパティが5000
(5秒)に設定された5つのメッセージを投稿すると仮定します。
Queue(main) (tail) { [4] [3] [2] [1] [0] } (head)
Queue(dead) (tail) { }(head)
次に、main
キューから3つのメッセージを消費し、10秒間保持します。
Queue(main) (tail) { [2!] [1!] [0!] } (head)
Queue(dead) (tail) { [4*] [3*] } (head)
感嘆符(!
)は、未確認のメッセージを表します。そのようなメッセージはどのコンシューマにも配信できず、通常は管理パネルで表示できません。ただし、消費者をキャンセルして、まだ3つの未確認メッセージを保持していることを思い出してください。
Queue(main) (tail) { } (head)
Queue(dead) (tail) { [2*] [1*] [0*] [4*] [3*] } (head)
そのため、先頭にあった3つのメッセージは元のキューに戻されましたが、メッセージごとにTTLが設定されているため、配信不能キューの末尾に配信されます( 、デッドレター交換経由)。
P.S.:
新しいメッセージをリッスンしているメッセージを消費することは、直接キューアクセス(他のメッセージを処理せずに1つ以上のメッセージを取得する)とは多少異なります。詳細については、 basic.get
メソッドの説明を参照してください。