2017-06-14 81 views
0

我有以下配置的RabbitMQ當消費者從RabbitMQ的,哪裏信道獲取消息預取消息駐留

prefetchCount:1 ACK模式:自動。

我有一個交換和一個隊列連接到該交換和一個消費者連接到該隊列。根據我的理解,下面的步驟將發生如果隊列有多條消息。

  1. 在一個通道上隊列寫入數據。
  2. 由於ack模式是自動的,只要隊列在通道上寫入消息,消息就會從隊列中刪除。
  3. 消息傳遞給消費者,消費者開始執行該數據。
  4. 由於Queue已經得到了前一條消息的確認,Queue將下一個數據寫入Channel。

現在,我的疑問是,假設消費者還沒有完成之前的數據呢。下一個數據隊列寫入通道會發生什麼?

另外,假設prefetchCount是10,並且我只有一次消費者連接隊列,這10個消息將駐留在哪裏?

回答

1

您描述的場景是在RabbitMQ文檔中提到的場景,詳細描述見this blog post。具體來說,如果您設置了足夠大的預取計數,並且發佈速率相對較低,那麼RabbitMQ服務器就會變成一個奇特的網絡交換機。當確認模式設置爲自動時,預取限制被有效禁用,因爲從來沒有未確認的消息。通過自動確認,消息在交付後立即得到確認。這與具有任意大的預取計數相同。

預取大於1時,消息存儲在客戶端庫的緩衝區中。確切的數據結構將取決於所使用的客戶端庫,但據我所知,所有實現都將消息存儲在RAM中。此外,使用自動確認功能,您無法知道特定消費者實際閱讀和處理消息的時間。

所以,有幾個外賣這裏:

  1. 預取限制是無關緊要的自動確認,因爲從未有任何未確認的消息,因此使用時
  2. 自動確認沒有多大意義消費者
  3. 當auto-ack處於關閉狀態時,或者使用autoack = on時,將進行足夠大的預取,這將導致消息代理不執行任何排隊,而僅執行路由。

現在,這裏有一些專家意見。我發現消息代理的整體概念「推動」消息有點倒退,出於這個原因,很難正確配置,並且不清楚它的好處是什麼。隊列系統自然適合拉式系統。當處理完當前消息後,處理器可以向代理詢問下一條消息。這種方法將確保負載自然平衡,並且在處理器斷開連接或被斷開時消息不會丟失。

因此,我的建議是放棄使用消費者,並切換到使用basic.get

+0

很好的答案,清除了很多疑惑,將切換到pull.One更多的事情,在我們目前的項目中,我們有以下場景,假設在隊列中的任何時候我們有記錄如下A-> B-> C,記錄C只能被處理了,A已經被處理了。這個實現是一樣的嗎?如果我們發現它的前任處理過的記錄尚未處理,那麼我們再次排隊記錄(而不是發送-nack,將通過交換進行排隊)。這將使我們的隊列記錄爲C-> A-> B,現在C將在A之後處理。 – Nishat

+0

感謝您的讚揚!如果您有其他問題,我建議您將問題張貼爲新問題,以便更方便地索取答案。我會評論說,所描述的情況似乎有點複雜的消息。 – theMayer

相關問題