【发布时间】:2017-06-29 06:36:03
【问题描述】:
我的应用程序的一部分需要一个恒定循环来检查我们的 ActiveMQ 消息队列是否“工作”。我已经使用在 Spring 初始化所有内容后启动的专用线程进行了设置,因此我拥有了我需要的所有 DI 项目。该线程现在处理 while(true) 循环中的所有内容,以便继续查找消息。
我正在设置一个 ActiveMQConnectionFactory 并注入它。使用该 AMQCF,在循环中我创建一个新的Connection,从连接中设置一个Session,设置一个Destination,最后查看MessageConsumer 到receive(5000)。如果检测到消息,我会处理它,一切都很好。
我的问题是我的应用程序和代理之间的连接问题。如果连接中断(AMQ 出现故障等),则会引发异常,一切都会崩溃。
javax.jms.JMSException: java.io.EOFException
at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:72)
at org.apache.activemq.ActiveMQMessageConsumer.dequeue(ActiveMQMessageConsumer.java:492)
at org.apache.activemq.ActiveMQMessageConsumer.receive(ActiveMQMessageConsumer.java:650)
at [AMQThreadClass]
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.EOFException
at java.io.DataInputStream.readInt(DataInputStream.java:392)
at org.apache.activemq.openwire.OpenWireFormat.unmarshal(OpenWireFormat.java:268)
at org.apache.activemq.transport.tcp.TcpTransport.readCommand(TcpTransport.java:240)
at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:232)
at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:215)
... 1 more
设置连接工厂时,我使用包含故障转移jms.location=failover:(tcp://localhost:61616)?reconnectDelayExponent=2.0&useExponentialBackOff=true&initialReconnectDelay=30&maxReconnectAttempts=0 的位置,我认为该位置可以工作。我认为可能还缺少其他一些东西,无论是循环还是我如何处理连接/会话/目标/消费者循环的想法。
有谁知道安全处理必然发生的连接问题的正确方法是什么?
【问题讨论】:
-
我没有使用过 ActiveMQ,所以我无法帮助你,但是当你说你的代码中有
while(true)时,我真的很害怕。如果一个 spring bean 需要启动线程,连接到套接字,那么你可能应该实现 SmartLifecyle,spring 会在上下文刷新和关闭时自动调用 start 和 stop。通常你有一个private volatile boolean shutdown,你在线程成功启动后设置为true,停止你设置shutdown=false,在你的线程内你有while(!shuitown)。 -
@KlausGroenbaek 我见过很多
while(!shutdown)样式循环来处理退出。那是接下来要做的事情:) 一步一步。感谢SmartLifecycle的建议,我会定义的。检查一下。