2013-03-08 229 views
6

保持持久隊列及其綁定但掛起其消費者的最佳方式是什麼?RabbitMQ掛起隊列消耗

用例如下:我想「讓它崩潰」並停止處理消息,如果我們收到一堆我們無法處理的消息(例如數據庫關閉或架構問題),但希望不斷聚合隊列。這是允許發佈但暫停使用。

我能想到的三種解決方案:

  1. 我可以綁定到隊列中的所有消費者不斷拒絕消息,並重新排隊,但這是有點浪費資源,更何況我已經編程做以上邏輯。
  2. 我可以打電話給basic.cancelConsumer上的所有消費者(見下文)的
  3. 還是在方面,我想我可以對所有綁定到隊列中的SimpleMessageListenerContainersshutdown

#1我們已經在做,因爲郵件正在被拒絕。問題是這最終會像一個無限的循環失敗,如果你的日誌記錄失敗,甚至更多的資源被浪費了。

#3似乎是理想的,但我必須知道一些如何知道所有的消息監聽器,然後通知他們關機。我想我可以使用扇出交換來通知隊列需要暫停。我覺得RabbitMQ必須爲這個邏輯內置一些東西。另一個問題是您可以將多個隊列綁定到消息容器(並非所有隊列都可能需要暫停)。

對於#2我知道我可以cancel the consumerconsumerTag但問題(假設是上面做正確的方式)是我在哪裏得到的consumerTag是清單到一個隊列?

回答

1

如果你需要停止一個消費者,那麼只需調用基本的取消,這是做到這一點的方法。

擁有持久隊列是您在申報隊列時解決的問題:durable=trueauto_delete=false

具有持久性消息是,當你把它們發佈決定:delivery_mode=2.

每個消費者都有自己的消費標籤。無論何時當您將消息從隊列中取出時,信封都應該有消費者標籤,您應該使用該標籤調用基本取消。 AFAIK,你不能在conn 1中擁有消費者A,並且在不同的連接上爲該消費者調用基本的取消。我可能在這個錯誤。

+0

謝謝。我知道如何在上面聲明像兔子一樣的隊列。看起來我必須自己管理我的消費者,這是我已經走下的路。如果兔子有明智的選擇來暫停隊列的使用,那將會很好。 – 2013-03-08 19:11:27

+0

你可以從連接做的唯一的事情是強制關閉它從管理員這不是你正在尋找 – 2013-03-08 20:48:50

1

此解決方案是具體。它的基本#3從我的答案。

我維護的隊列名稱爲Map<String,CustomSimpleMessageListenerContainer>的服務定製擴展爲SimpleMessageListenerContainer

經過一定數量的例外之後,我發送一個「恐慌」消息,該消息進入服務收到的特殊隊列以關閉消費者。