2011-11-22 78 views
1

假設您有兩個Spring DefaultMessageListenerContainer監聽同一個隊列(例如ActiveMQ),並在不同的VM中啓動。使用JMX + ActiveMQ管理的DefaultMessageListenerContainer單個隊列上的多個使用者

發送1000000條消息。在你想讓剩下的消息只有一個DefaultMessageListenerContainer處理500,000條消息之後,BUT不會另外調用銷燬或關機(因爲將來可能需要它 - 並且必須保持JMX的可管理性)。這些數字僅僅是在這裏,應該忽略,可以用 - 「經過一段時間後,在一些消息等等之後」等等。

這聽起來很簡單:呼叫停止在另一個DefaultMessageListenerContainer。錯誤,因爲消息是以循環方式發送的,並且它們已經被消費者註冊。

每次消息進入時添加事務支持並在第二個DefaultMessageListenerContainer中拋出錯誤,它將被回滾並且被第一個消息(循環)取回。錯誤再次,消息以某種方式向消費者註冊,不允許第一個DefaultMessageListenerContainer消息。

即使您關閉/銷燬第一個DMLC,該消息也不會被其他DMLC消耗。只有當我終止現在關閉/銷燬的DMLC正在運行的JVM時,它們才被使用。

我的解決方案到目前爲止:由於Session.AUTO_ACKNOWLEDGE消息在隊列中輸入onMessage方法之前從MessageListener DefaultMessageListenerContainer。在MessageListener實施SessionAwareMessageListener並重新發送具有相同有效負載的消息的副本。 但是這看起來真的很髒 - 我希望我能以「JMS」的方式做更多。

+0

而你的問題是? – nfechner

+0

好吧,我可以「註銷」來自特定消費者的消息嗎? – Eugene

回答

1

我不完全掌握這部分:「[消息]向消費者註冊」。你的意思是說ActiveMQ決定把它發送給哪個監聽器?當您在DMLC上調用「stop」時究竟發生了什麼?

我不知道這是否會克服你的困難,但這裏有一個想法:在DMLCs中的消息選擇器是:你可以隨時改變它們,它們立即生效。也許嘗試將消息選擇器更改爲「FALSE」;所有緩存的消息應該完成處理,新的消息應該停止。

+0

事實上,我忘了提及我也嘗試過消息選擇器 - 它不起作用。當你在MDLC上調用stop()會發生什麼?這裏是一個例子:兩個DMLC都啓動,每個內部的onMessage方法輸出有效載荷。我發送兩條消息,其中一個DMLC的輸出爲「1111」,另一個爲「2222」。我停止一個DMLC併發送兩個,第一個輸出爲「3333」,第二個輸出爲「3333」。我從第二個開始:輸出是「4444」。希望這是明確的 – Eugene

+0

@Eugene你能解釋一下嗎?正如我的答案的第一部分所表明的那樣? – MaDa

+0

看來,內部的ActiveMQ與默認的輪詢策略以某種方式註冊每個消息與特定的消費者,並保持此順序。您看到當您有一個隊列有多個使用者時會發生什麼情況並未在JMS中指定。由供應商決定。我今天將再次在Tibco EMS上進行測試併發布結果 – Eugene

相關問題