2014-11-21 61 views
4

當使用RabbitMQ作爲Message Broker時,我有一個場景,其中多個併發使用者使用basic.get AMQP方法從隊列中提取消息,並使用顯式確認從隊列中刪除消息。假設以下設置:Q具有消息M1,M2,M3,並且消費者C1,C2和C3(每個都具有其自己的連接和信道)連接到其上。AMQP basic.get併發消費者從隊列中提取

  1. 如何在basic.get方法中處理併發性?是否同步調用basic.get方法來處理每個使用自己的連接和通道的併發使用者? C1,C2和C3發出一個basic.get調用來同時接收一條消息(假設服務器同時收到所有3個請求)。

  2. C1使用basic.get請求消息並獲取M1。當C2請求消息時,由於它使用不同的連接,它是否再次獲得M1?

  3. 消費者如何以預定義的尺寸批量提取消息?

+1

目前尚不清楚你的問題是什麼。 – pinepain 2014-11-21 19:43:07

+0

第二點是NO。其他的點我不明白! 「同步處理併發消費者」意味着什麼? RMQ是一個FIFO系統,所以你把3條消息和C1獲得第一,C2的秒......等等......假設你正在使用prefetch = 1。 – Gabriele 2014-11-22 08:58:52

+0

我的答案在下面有幫助嗎?如果是這樣,請將其標記爲答案。如果沒有,我該如何詳細說明? – theMayer 2015-07-08 20:47:43

回答

-1

該方案沒有特別的配置要求。每個客戶端都會自動從隊列中獲取並接收一條消息,就像您希望發生的一樣。

+0

那麼,RabbitMQ是否處理同步部分?它是否在basic.get請求上實現了一些鎖定? – 2014-11-22 02:55:48

+0

改寫我的問題:basic.get上的同步如何處理?有沒有對basic.get請求進行一些鎖定? – 2014-11-22 03:12:31

1

您可能想要閱讀RabbitMQ Api guideintroduction to Amqp

首先,避免在消費者中使用使用basicGet的消息。而是使用消費者界面basicConsume。這允許RabbitMq在消息到達隊列時推送消息。其他一切都是資源的束縛,因爲它歸結爲忙碌的投票。

使用basicConsume時,RabbitMq甚至會在後臺向您推送更多的消息,直到某個prefetch計數。這允許您同時處理多條消息,並最小化等待下一條消息處理的時間(如果有某條消息可用)。

併發並不是一個問題,這就是你正在使用的隊列! 當一個隊列上有多個使用者時,消息總是隻會傳遞給一個使用者(只要該消息已被確認)。否則,您需要爲每個消費者提供專用隊列,並相應地發送消息。

順便說一句,如果你能夠分享你的消費者之間的連接,你應該這樣做。 只要確保每個線程使用一個通道。

+0

使用pull方法與push方法來檢索消息是有正當理由的。 – theMayer 2014-11-23 15:00:15

+0

當然,拉方法有很好的理由!我只是不認爲它是典型的用例。 – Moritz 2014-11-23 15:52:51

+0

這確實是程序語義問題,因爲應用程序的結果行爲是相同的。 – theMayer 2014-11-23 15:54:10

7

你的問題真的觸及排隊和過程理論的核心,所以我會從這個觀點回答(就我的答案而言,RabbitMQ真的是一個通用的消息代理,因爲這適用於任何消息代理)。

在basic.get方法中如何處理併發性?是否調用 basic.get方法同步處理併發消費者每個 使用自己的連接和通道? C1,C2和C3發出一個basic.get 調用來同時接收一條消息(假設服務器同時接收到所有3個請求的 )。

回答1:RabbitMQ被設計成一個可靠的消息代理。它包含內部流程和控制,以確保相同的消息不會多次傳遞給不同的消費者。現在,由於測試您描述的場景的不切實際,它完美地工作嗎?誰知道。這就是爲什麼使用基於消息的體系結構的正確設計的應用程序將使用冪等事務,因此如果多次處理同一事務,結果將與事務處理一次相同。 外賣:設計你的應用程序,以便這個問題的答案是不重要的。

C1使用basic.get請求消息並獲取M1。當C2請求 作爲消息時,由於它使用不同的連接,它是否再次獲得M1 ?

答2:不可以按照我以前的答案的假設,RabbitMQ的經紀人將不會提供同樣的信息回來一次它已送達。根據通道和隊列的設置,消息可能會在交付時自動確認,並且不會重新發送。其他設置將在處理線程/通道「死亡」或來自處理線程的否定確認後自動產生消息。這是重要的功能,因爲如果可以向多個消費者提供「毒藥」消息,它可能會在應用程序中反覆肆虐。 外賣:您可以放心地依靠這個假設來設計您的應用程序。

消費者如何以預定義的尺寸批量提取消息?

答案:他們不能,也不會對他們有意義。在任何排隊系統中,基本假設是項目在單個文件中從隊列中移除。試圖違反這一假設會導致不可預知的行爲;此外,單件流程通常是最有效的處理方法。但是,在現實世界中,有時批量大小> 1是必要的。在這種情況下,將批處理加載到它自己的單個消息中是有意義的,因此這可能需要一個單獨的處理線程,從隊列中提取消息並將它們批處理或最初批處理。請記住,一旦有多個消費者,就沒有辦法保證單個消息將按順序處理。 外賣:應儘可能避免批量生產,但在避免不實際的情況下,您可能不會認爲批次將以任何特定順序包含單個消息。