2010-11-29 55 views
3

我在寫一個從隊列中消費的JMS客戶端。我的經紀人是activemq,如果它很重要。ActiveMQ:沒有經紀人的初始消費者

一個要求是即使代理已關閉,客戶端也應該啓動。在這種情況下,它應該像在隊列中沒有消息一樣,並且一旦代理啓動並且消息開始相應地行爲。

的問題是,在我的代碼:

connectionFactory = new ActiveMQConnectionFactory(url); 
Connection connection = connectionFactory.createConnection(); 
connection.start() 

如果代理下來,那麼它陷在connection.start()。雖然我想要的是connection.start()以靜默方式返回並繼續嘗試在後臺進行連接,並在消息可用時使用消息,並在消息不能時保持消息。

我該如何做到這一點。

回答

1

使用單獨的線程從隊列中消耗並啓動連接。您將需要使用併發隊列實現。

線程1:

  • 實例化隊列
  • 開始線程2
  • 嘗試連接/塊
  • 添加消息到隊列

線程2(或一些池分類):

  • 啓動客戶端
  • 從隊列/塊讀取
  • 處理消息
+0

它是JMS隊列還是它的線程間通信隊列? – dimba 2011-02-26 20:50:29

0

我覺得ActiveMQ的有協議(許多協議....)來改變連接的行爲。嘗試使用'failover://'或類似的東西在你的網址,看看它是如何工作的。

0

我現在正在處理這個問題。請參閱AMQ-2114

我不太明白接受的答案,所以我提出賞金。

我使用的是C++版本的ActiveMQ。但我相信這不應該有很大的不同。

我想過在獨立的線程中調用connection.start(),並調用connection-> createSession()在TransportListener :: transportResumed()中。但是,createSession掛起。底線,我沒有工作解決方案,我很高興知道解決問題的其他方法。

1

有兩種方法可以解決此類型的場景,其中一個在AMQ-2114描述:

  1. 通過使用代理的URI在AMQ-2114建議。通過使用AMQ-2114中建議的代理URI,可以創建嵌入式代理,並通過網絡連接到遠程代理。但是,正如所指出的那樣,代理URI不使用故障轉移連接器。

  2. 通過使用手動配置爲使用代理網絡的嵌入式代理。過去,我已經使用過這種方法,其中一個ActiveMQ代理實例嵌入到您的Java應用程序中,並通過網絡連接配置到遠程代理。這將允許您的客戶端連接到嵌入式代理而不掛起,並將消息發送給嵌入式代理。只有消費者需要遠程代理上的消息(即消費者連接到遠程代理和請求消息)時,消息纔會從嵌入式代理流向遠程代理。與嵌入式代理的連接可以使用故障轉移傳輸,並且與遠程代理的網絡連接也可以使用故障轉移傳輸。

我給這個解決方案的例子是一個用例是銷售人員筆記本電腦上的Java應用程序。即使銷售人員沒有連接到他們的辦公網絡,這樣的應用程序也需要繼續工作。這裏的解決方案是在Java應用程序中嵌入一個代理程序,以便在發送消息時應用程序不會掛起,即使它沒有連接到辦公室網絡。當應用程序再次連接到辦公室網絡時,它將自動連接到另一個代理,並且消息將流動。

布魯斯

1

只是爲了子孫後代,我會強烈建議使用Spring的使用DefaultMessageListenerContainer用於消費的消息,一旦配置使用以下code snippet

<jms:listener-container> 
    <jms:listener destination="queue.orders" ref="orderService" method="placeOrder"/> 
</jms:listener-container> 

則需連接到與JMS隊列基礎設施的護理您的特定需求(如果JMS基礎架構停機,應用程序上下文仍會加載,但重試線程會每隔幾秒嘗試恢復連接)。