2010-11-29 58 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基础架构停机,应用程序上下文仍会加载,但重试线程会每隔几秒尝试恢复连接)。