83

私は RabbitMQ を使用しており、電子メール メッセージを保持するキューがあります。私の消費者サービスはメッセージをデキューし、それらを送信しようとします。何らかの理由でコンシューマがメッセージを送信できない場合、メッセージを再キューイングして再度送信したいと考えています。basicNack を実行して requeue フラグを true に設定できることはわかっていますが、メッセージを無期限に再キューに入れたくはありません (たとえば、メール システムがダウンした場合に、未送信のメッセージを継続的に再キューに入れたくはありません)。メッセージをキューに入れ直して再送信できる回数を定義したいと思います。ただし、電子メール メッセージ オブジェクトをデキューして nack を送信すると、フィールドを設定できません。更新されたフィールドは、キュー内のメッセージに存在しません。これにアプローチできる他の方法はありますか?前もって感謝します。

4

3 に答える 3

95

RabbitMQ (および AMQP プロトコル) には、再試行のような機能はありません。

再試行制限動作を実装するための可能な解決策:

  1. 以前に再配信されていない場合はメッセージを再配信し (メソッドのredeliveredパラメーターを確認しbasic.deliverてください - ライブラリにはこのためのインターフェースが必要です)、メッセージをドロップしてから、dead letter exchangeでキャッチし、何らかの方法で処理します。

  2. メッセージを処理できないたびに再度発行しますが、ヘッダー フィールドを設定またはインクリメント/デクリメントしますx-redelivered-count(ただし、任意の名前を選択できます)。この場合に再配信を制御するには、設定したフィールドが制限に達しているかどうかを確認する必要があります (上または下 - 0 が私の選択で、ttltcp/ip からの IP ヘッダーの a-la)。

  3. メッセージの一意のキー (uuid と言いますが、メッセージを発行するときに手動で設定する必要があります) を Redis、memcache、またはその他のストレージに格納します。再配信カウントと一緒に mysql に保存し、再配信ごとにこの値を制限に達するまで増減します。 .

  4. (本当のマニア向け)必要に応じてそのような動作を実装するプラグインを作成します。

#3の長所は、再配信されたメッセージがキューの先頭に留まることです。これは、キューが長い場合、またはメッセージの順序が重要な場合に重要です (再配信は厳密なメッセージの順序を破ることに注意してください。詳細については、公式ドキュメントまたはSO に関するこの質問を参照してください)。

PS:

このトピックにも同様の回答がありますが、php. それをよく見てください。少し役立つかもしれません ( 「サイクル再配信の問題に対処するための複数の手法があります」という言葉から読み始めてください。

于 2014-04-18T20:37:37.817 に答える