私は RabbitMQ を使用しており、電子メール メッセージを保持するキューがあります。私の消費者サービスはメッセージをデキューし、それらを送信しようとします。何らかの理由でコンシューマがメッセージを送信できない場合、メッセージを再キューイングして再度送信したいと考えています。basicNack を実行して requeue フラグを true に設定できることはわかっていますが、メッセージを無期限に再キューに入れたくはありません (たとえば、メール システムがダウンした場合に、未送信のメッセージを継続的に再キューに入れたくはありません)。メッセージをキューに入れ直して再送信できる回数を定義したいと思います。ただし、電子メール メッセージ オブジェクトをデキューして nack を送信すると、フィールドを設定できません。更新されたフィールドは、キュー内のメッセージに存在しません。これにアプローチできる他の方法はありますか?前もって感謝します。
3 に答える
RabbitMQ (および AMQP プロトコル) には、再試行のような機能はありません。
再試行制限動作を実装するための可能な解決策:
以前に再配信されていない場合はメッセージを再配信し (メソッドの
redelivered
パラメーターを確認しbasic.deliver
てください - ライブラリにはこのためのインターフェースが必要です)、メッセージをドロップしてから、dead letter exchangeでキャッチし、何らかの方法で処理します。メッセージを処理できないたびに再度発行しますが、ヘッダー フィールドを設定またはインクリメント/デクリメントします
x-redelivered-count
(ただし、任意の名前を選択できます)。この場合に再配信を制御するには、設定したフィールドが制限に達しているかどうかを確認する必要があります (上または下 - 0 が私の選択で、ttl
tcp/ip からの IP ヘッダーの a-la)。メッセージの一意のキー (uuid と言いますが、メッセージを発行するときに手動で設定する必要があります) を Redis、memcache、またはその他のストレージに格納します。再配信カウントと一緒に mysql に保存し、再配信ごとにこの値を制限に達するまで増減します。 .
(本当のマニア向け)必要に応じてそのような動作を実装するプラグインを作成します。
#3の長所は、再配信されたメッセージがキューの先頭に留まることです。これは、キューが長い場合、またはメッセージの順序が重要な場合に重要です (再配信は厳密なメッセージの順序を破ることに注意してください。詳細については、公式ドキュメントまたはSO に関するこの質問を参照してください)。
PS:
このトピックにも同様の回答がありますが、php. それをよく見てください。少し役立つかもしれません ( 「サイクル再配信の問題に対処するための複数の手法があります」という言葉から読み始めてください。