2012-10-30 99 views
5

我有一個發佈 - 訂閱用例,我想阻止發佈方,直到每個訂戶確認他們已完成處理髮布者發送的消息。爲什麼Channel.waitForConfirmsOrDie不能阻止?

我(錯誤地?)認爲我可以使用RabbitMQ及其Java amqp-client的Channel.waitForConfirmsOrDie方法作爲我的解決方案的一部分。問題是,我還沒有發現waitForConfirmsOrDie會實際阻止的情況。

按照javadocs,waitForConfirmsOrDie應該是:

等待,直到自上次調用發佈的所有消息已要麼ack'd或由經紀人nack'd。如果任何消息被拒絕,waitForConfirmsOrDie將拋出IOException。在非確認通道上調用時,將立即返回。

爲了測試這種方法是否真的起作用,我從this example code from the RabbitMQ website開始。

示例代碼創建一個發佈者和一個消費者,每個消息都在其自己的單獨線程上。然後,發佈者在消費者使用消息時將消息發送到交換機。看起來,發佈者應該阻止,直到所有的消息都通過waitForConfirmsOrDie()調用進行響應。

這個示例代碼看起來像它與我正在嘗試做的完全匹配。但是,它似乎並不像我認爲的那樣工作。事實上,如果在消費者線程中關閉了自動確認消息,那麼waitForConfirmsOrDie()仍然會立即返回。

我關掉自動應答僅通過改變一個假爲真: ch.queueDeclare(QUEUE_NAME, false, false, false, null); 成爲 ch.queueDeclare(QUEUE_NAME, true, false, false, null);(第二ARG假,而不是真正的)。我相信這意味着消費者不應再發送消息。

那麼waitForConfirmsOrDie()實際上做了什麼?它何時會阻止?

如果waitForConfirmsOrDie沒有做我想做的事,有沒有辦法讓發佈商等待,直到所有訂閱者在繼續之前回復一條消息?

回答

7

據我瞭解,這些電話不應等待消費者的確認。 waitForConfirms*方法的目的是確保您的消息已交付給代理,並提供基本的交付/失敗類型的通知。換句話說,如果rmq節點(或者甚至所有節點)中的一個節點失敗/不可用,則消息不會消失而不通知產生。

如果在basicPublish調用之前斷開或關閉rmq,則可以看到此異常正在執行。

相關問題