2012-03-14 79 views
36

我們有一個應用程序將使用RabbitMQ,並有幾個不同的隊列用於在層之間傳遞消息。主題交換與RabbitMQ中的直接交換

最初,我打算使用多個直接交換機,每個消息類型都有一個交換機,但它看起來像使用不同的路由鍵綁定的單個主題交換隊列將實現相同的目的。

有一次交換也似乎會更容易維護,但我想知道是否有任何好處(如果有的話)做到這一點比其他方式更好?

選項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") 

回答

29

假設這兩種模式都被認爲是使用一個代理的運行來實現,幾乎沒有區別,我可以看到。

選項2似乎在現實世界中更常見,用於解決這種路由問題(至少在我的軼事經驗中),這正是主題交換存在要解決的挑戰。

您可能遇到的唯一區別將與路由速度有關。我不確定在RabbitMQ中,與主題交換中使用的路由關鍵字技術(可能包含通配符如#*)相比,Exchange路由是否更快(總是基於精確的字符串匹配)。我的預感是Exchange的歧視會更快,但你可以嘗試自己找出答案,或嘗試聯繫RabbitMQ團隊詢問他們。

最後,如果你選擇1結束了大量的隊列,那麼你將有一個交易所的比例激增。這聽起來像是一個維修頭痛。如果你只有少數隊列,那麼它不會成爲太多問題。

+2

我同意。使用適當的路由密鑰的多個隊列更容易管理。想到選項1的唯一優點是可以在單獨的硬件上託管多個交換機,從而實現垂直縮放。但是,如果你的硬件很不穩定,那麼你可能永遠都不需要採用這條路線。 – 2012-03-14 22:03:01

+0

我認爲使用Topic的好處在於,如果將來您需要將相同的消息發送到交換中的多個隊列,那麼您的選項2會更可取。 – gigi2 2014-04-03 18:02:38

3

對於負載很小的單個小節點,幾乎沒有區別。由於上述原因,大多數人都選擇了第二種選擇。

在設計系統時,你應該問問你自己未來如何擴展。

它如何擴展?
我需要它來縮放嗎? 我想在未來添加高可用性羣集嗎? 我的路由將改變...

選項2在大多數情況下提供了更多的靈活性。

它允許您使用自己的隊列將新消費者附加到Exchange,並輕鬆捕獲任何子集或全部消息流。 (這些隊列可能位於羣集中的其他節點上,或鏡像到n個節點以提供故障轉移)。典型的用例是使用第4個隊列記錄所有消息。

如果您的瓶頸在處理方面,您還可以進一步細分您的消息主題,並執行一些優先級排序而不必更改發佈者。例如:ToppicA.urgent,由專用消費者處理,最終處理TopicA.log。

簡短的答案與選項2一起使用,除非您有非常特定的性能要求。例如,如果您需要處理超過50k msg/s的持續速率,則可能需要考慮專用節點上的選項1,但對於正常流量,選項2將更容易擴展和維護。

4

實際上,方法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 ......你仍然可以保持單一的直接交換。