2017-07-14 93 views
2

我知道在主題交換中實現循環法行爲可能會非常棘手或根本無法實現,所以我的問題實際上是,如果我能從RabbitMQ中做出任何事情或者望向其他消息隊列支持。如何在RabbitMQ中實現循環法主題交換

這裏是我的應用需求進行詳細的解釋:

  1. 將有一個製片人,我們稱之爲P
  2. 有(可能)將是成千上萬的消費者,我們姑且稱之爲Cn
  3. 每消費者可以「訂閱」1個或多個話題交換並且多個消費者可以訂閱同一主題
  4. 發佈到該話題中的每個消息應該僅被一個消費者消費

使用案例#1

假設:

主題

  • foo.bar
  • foo.baz

消費者

  • 消費者C1訂閱主題#
  • 消費者C2訂閱主題foo.*
  • 消費者C3訂閱主題*.bar

生產者P公佈下列信息:

  1. 發佈foo.quxC1C2可以潛在地消耗該消息,但只有一個接收它
  2. 發佈foo.barC1C2C3可以潛在地消耗該消息,但只有一個接收它

注意 不幸的是,我不能爲每個「主題」有一個單獨的隊列,因此使用Direct Exchange不工作k因爲主題組合的數量可能很大(數以萬計)

從我讀過的內容來看,RabbitMQ沒有開箱即用的解決方案。有人知道解決方法,或者有另一個消息隊列解決方案可以支持這一點,例如。卡夫卡,Kinesis等

謝謝

+1

雖然我理解了這個問題,並發現它的反常性非常有趣(這可以說是100%足夠的問題),但我也很好奇這個用例。在我看來,話題交換旨在發佈關於「主題」的消息,並讓「人們」對某種類型的接收消息感興趣。沒有看到任何方式可以有效地從主題交換中「產生/消耗」,但我一定是錯的。就我個人而言,除了推遲使用某些數據存儲選舉獲勝的消費者之外,我沒有看到任何其他方式。我可能是錯的,我對卡夫卡和Kinesis瞭解不多。 – user1527491

+1

我的觀點是:如果所有(或某些)消費者都被告知已發送消息,則使用話題交換。如果只有一個消費者必須以生產者/消費者的方式消費該消息,則使用直接或扇出交換。如果您需要兩者,請同時使用!發佈到兩個交易所。但這並不能解決問題,事實上,因爲你的消費者會有錯誤的消費者。 – user1527491

+0

順便說一下,雖然我不是卡夫卡的專家,但我99%確信它不會幫助(甚至會更糟糕),因爲它根本沒有路由的概念。這是pub/sub更糟或更好的,這意味着它甚至不會幫助生產者/消費者的東西。請注意,即使RabbitMQ也不保證一次交付。 – user1527491

回答

1

似乎有交流,這是路由信息的角色糅合在一起,和隊列,這是等待處理的消息提供一個固定的地方。將消息彙集到一個或多個隊列是交換的工作,而將消息從隊列彙集到多個消費者是隊列的工作。循環賽只適用於後者。

基本上,topic交換是通過複製消息來操作的,每個消息與用消息發佈的主題相匹配。因此,任何對循環賽行爲的期望都是錯誤的,因爲它違背了交易所的定義。

所有這一切只是確定,根據定義,問題中提出的方案沒有意義。那而不是意味着期望的行爲是不可能的,但是術語和拓撲可能需要一些明確的調整。讓我們回過頭來看一條消息的描述的生命週期:它由一個生產者生產,並由許多消費者之一消費。通常,這是直接交換所解決的情況。其中一個複雜的因素是,你的消費者對他們將消費什麼類型的消息進行選擇(或者換句話說,你的生產者對它產生的消息類型不一致)。

通常在面向消息的處理中,單個消息類型對應於單個消費者類型。因此,每種不同類型的消息都會得到自己對應的隊列。但是,根據此問題中給出的描述,單個消息類型可能對應於多種不同的消費者類型。有一個問題我有如下語句:

可惜我不能有一個單獨的隊列,每個「主題」

表面上看,這種說法是沒有意義的,因爲它真正說是你有任意多的(實際上是未知數量的)消息類型;如果是這種情況,那麼你將如何編寫代碼來處理它們?

所以,忽視了一下這句話,我們都導致了與RabbitMQ的兩種可能性的開箱:

  1. 使用直接交換和發佈使用消息的輸入消息的路由鍵。然後,讓您的各種消費者只訂閱他們可以處理的消息類型。 這是最常見的消息處理模式。

  2. 使用主題交換,並提供某種外部重複數據刪除邏輯(可能是memcached),其中檢查消息並將其丟棄,如果其他消費者已開始處理它。

現在,它們都沒有明確處理循環法要求。既然沒有解釋爲什麼這個問題很重要,那麼可以忽略它。如果不是,則需要進一步定義問題空間。

+0

的確,我尋求使用RabbitMQ的方式並不是它所設計的。然而,因爲沒有工具可以提供這些(至少從我所知道的),我試圖彎曲消息代理的原則來涵蓋我的用例。 關於_很遺憾,我不能爲每個「topic」設置一個單獨的隊列_:並不是說消息是不同的,只會有一種消息類型,但是針對不同的消費者羣體,其中只有一個消費者被隨機挑選來處理它。 –

+0

那麼,有工具,但沒有*一個工具* - 但是,當那裏有?如果所有事情都做到了你需要的東西,那麼對程序員的需求會非常低。 :) – theMayer

+0

根據您的評論的後半部分,聽起來您會爲每個消費者組創建一個隊列,然後設置您的消費者從適當的隊列中拉出。這是RabbitMQ中的默認功能。 – theMayer