58

RabbitMQを使用し、層間でメッセージを渡すためのいくつかの異なるキューを持つアプリケーションがあります。

当初は、メッセージタイプごとに1つずつ、複数の直接交換を使用することを計画していましたが、異なるルーティングキーバインディングを使用するキューで単一のトピック交換を行うと、同じことが達成されるようです。

単一の交換を行うことも、保守が少し簡単になるように思われますが、一方の方法でそれを行うことの利点(ある場合)があるかどうか疑問に思いました。

オプション1、複数の直接交換を使用:

ExchangeA (type: direct)
-QueueA

ExchangeB (type: direct)
-QueueB

ExchangeC (type: direct)
-QueueC

オプション2、単一トピック交換を使用:

Exchange (type: topic)
-QueueA  (receives messages from exchange with routing key of "TypeA")
-QueueB  (receives messages from exchange with routing key of "TypeB")
-QueueC  (receives messages from exchange with routing key of "TypeC")
4

5 に答える 5

39

両方のモデルが実行中の1つのブローカーを使用して実装されていると見なされていると仮定すると、私が見ることができる違いはほとんどありません。

オプション2は、この種のルーティングの問題を解決するために現実の世界でより一般的であるように思われ(少なくとも私の逸話的な経験では)、トピック交換が解決するために存在する課題です。

発生する可能性がある唯一の違いは、ルーティング速度に関連します。#トピックExchangeで使用されるルーティングキー手法(やなどのワイルドカードを含めることができる)と比較した場合、RabbitMQでExchangeルーティング(常に完全な文字列の一致に基づく)が高速であるかどうかはわかりません*。私の勘では、Exchangeの識別がより高速になると思いますが、自分で実験して調べたり、RabbitMQチームに連絡して質問したりすることもできます。

最後に、オプション1を選択すると、キューが大量に発生することになり、Exchangeが比例して急増します。それはメンテナンスの頭痛の種のように聞こえます。キューがほんの一握りしかない場合は、それほど問題にはなりません。

于 2012-03-14T20:20:17.783 に答える
25

実際、アプローチ2は、複数のルーティングキーに単一のキューを使用する柔軟性を提供するため、より優れています。

交換トピック

QueueA-- binding key = India.Karnataka.*

ルーティングキーをIndia.Karnataka.bangalore、India.Karnataka.Mysoreとして、メッセージをトピック交換にルーティングできます。

上記のメッセージはすべてQueueAに送信されます。

直接交換

しかし、アプローチ1で複数の直接交換を作成する理由がわかりませんでした。単一の直接交換を行い、各キューが一意のキーでバインドされた複数のキューを持つことができます。

QueueA-- binding key = Key1
QueueB-- binding Key = Key2
QueueC-- binding Key = Key3

すべてのkey1メッセージはQueueAに送られます。Key2はQueueBに送られます...単一の直接交換を維持できます。

于 2017-04-25T15:44:43.067 に答える
7

負荷が少ない単一の小さなノードの場合、違いはほとんどありません。上記の理由から、ほとんどの人はオプション2を選択します。

システムを設計するときは、これが将来どのように拡張されるかを自問する必要があります。

どのようにスケーリングしますか?
スケーリングする必要がありますか?将来、高可用性クラスターを追加しますか?ルーティングは変更されますか...

オプション2は、ほとんどの場合、はるかに柔軟性があります。

これにより、新しいコンシューマーを独自のキューを使用してExchangeに接続し、メッセージフローのサブセットまたはすべてを簡単にキャプチャするなどのことができます。(これらのキューは、クラスター内の他のノードにあるか、フェイルオーバーを提供するnノードにミラーリングされている可能性があります)一般的な使用例は、4番目のキューを使用してすべてのメッセージをログに記録することです。

ボトルネックが処理側にある場合は、メッセージトピックをさらに細かく分割し、発行元を変更せずにある程度の優先順位付けを実行することもできます。例:専用のコンシューマーによって処理されたToppicA.urgent、最終的に処理されたTopicA.log。

非常に具体的なパフォーマンス要件がない限り、簡単な答えはオプション2を使用することです。たとえば、50k msg / sを超える持続レートを処理する必要がある場合は、専用ノードでオプション1を検討することをお勧めしますが、通常のフローの場合オプション2は、スケーリングと保守が容易になります。

于 2015-04-15T05:19:32.330 に答える
0

直接交換は複数のルートもサポートしているため(https://www.rabbitmq.com/tutorials/amqp-concepts.html#exchange-direct)、次のようなものを使用してみませんか。

ExchangeA (type: direct)
-QueueA
-RoutingA

ExchangeB (type: direct)
-QueueB
-RoutingB

ExchangeC (type: direct)
-QueueC
-RoutingC
于 2019-08-21T20:50:26.520 に答える
0

また、メッセージを公開するためのコードは、異なるエクスチェンジに公開する場合と、単一のエクスチェンジに公開する場合で、ルーティングキーが異なる場合とではわずかに異なるように見えることも考慮する必要があります。

コードはどこかから(おそらく構成から)さまざまな交換の名前を知る必要があり、交換とルーティングキーの間の一種のマッピングを維持する必要があることに注意してください。また、RabbitMQでの直接交換では、ルーティングキーがキュー名と正確に一致する必要があります。したがって、コードは、正しいルーティングキーを設定できるように、キュー名も知る必要があります。

単一の交換を使用する場合(直接またはトピックに関係なく)、コードは1つの交換とルーティングキーのみを処理する必要があります。

于 2020-02-11T15:11:25.943 に答える