web-dev-qa-db-ja.com

重複メッセージを削除するRabbitMQプラグイン

ドキュメント生成用のRabbitMQキューがあります。基本的に、各ドキュメントにはtypestate(新規、処理中、準備完了)があるため、type.stateのようなルーティングキーを使用してトピック交換を使用します。ドキュメントが変更されるたびに、最後のドキュメントの説明を含むメッセージを取引所に送信します。これで十分に機能します。

ただし、ドキュメントを2回処理できる場合があります。

  1. ユーザーが新しいドキュメントを送信します。そのため、新しいメッセージreport.newが交換に送信されます。
  2. ワーカーがドキュメント処理を開始していない間(キューがまだ到達していない)、ユーザーはドキュメントを更新しました。同じドキュメントの新しいメッセージreport.newが送信されます。
  3. だから今、労働者は最初のメッセージを受け取り、彼の仕事を始めますが、ドキュメントは変更されているので、この仕事はまったく無意味です。

今のところ、ワーカーに小さなコードを追加し、メッセージのlast_modifiedドキュメントキーをデータベースのキーと比較して、同じでない場合はメッセージを確認します。しかし、これが最善の解決策ではないと思います。

私の考えは、メッセージヘッダーにIDを追加し、同じIDを持つ古いメッセージをキューから削除するRabbitMQプラグインを用意することです。

ありがとう。

追伸たぶん、別のMQエンジンがここで役立つ可能性がありますか?例えば。多分ActiveMQはそのような機能を持っていますか?

6
Ximik

わかりました。RabbitMQの内部アーキテクチャについて読んだところ、不可能であることがわかりました。それで、それを探している誰かのための道。

  1. メッセージ本文でドキュメントIDのみを送信する
  2. ワーカー用のKey-Valueストアを作成します(これにはmemcachedを使用します)。キーはID値は、このIDに対して最後に実行されたワーカーのタイムスタンプです。
  3. ワーカーはメッセージを受信すると、メッセージのタイムスタンプがKey-Valueストアのタイムスタンプよりも大きいかどうかを確認します。そうである場合は、ストアのタイムスタンプを更新してタスクを実行します。そうでない場合は、スキップします。
8
Ximik

あなたはこれをチェックすることができます プラグイン ブローカー内で公開されたメッセージを重複排除することを可能にする私が書いた。

必要に応じて、取引所またはキューで重複排除を行うことができます。パブリッシャーが行う必要があるのは、x-deduplicate-messageメッセージヘッダーをメッセージのIDで設定することだけです。

5
noxdafox

あなたが書いたように、 ActiveMQには「重複メッセージ検出」があります ですが、動作が異なります。キューから古いメッセージを削除することはありませんが、代わりに新しいメッセージを追加することはありません。したがって、 RabbitMQのプラグイン と同じように機能します。

1
Mišo