我有一个应用程序,它读取来自HornetQ的JMS消息。
<int-jms:message-driven-channel-adapter
id="myJmsChannelAdapter"
channel="myJmsChannel"
connection-factory="myCredentialsConnectionFactory"
destination-name="${my.jms.topic}"
pub-sub-domain="true"
subscription-durable="${my.jms.subscription.durable}"
client-id="${my.jms.client.id}"
durable-subscription-name="${my.jms.subscription.name}"
/>
当消息到达时,我通过轮询器处理它们
<!-- Send Jms message one by one to creation -->
<int:bridge input-channel="myJmsChannel" output-channel="jmsMessageCreateInputChannel">
<int:poller max-messages-per-poll="1" fixed-delay="100">
<int:transactional transaction-manager="transactionManager" propagation="REQUIRES_NEW"/>
</int:poller>
</int:bridge>
轮询器调用一个链,该链在我的数据库中存储消息的内容
<chain id="jmsMessageCreate" input-channel="jmsMessageCreateInputChannel">
<!-- extract the operation from the message itself -->
<int-xml:xpath-header-enricher>
<int-xml:header name="operation" xpath-expression="name(./node())" overwrite="true"/>
</int-xml:xpath-header-enricher>
<service-activator expression="@jmsMessageService.createNewJmsMessage(payload, headers['operation'])"/>
<!-- have a JPA entity in the payload -->
<gateway request-channel="persistEntityChannel"/>
<logging-channel-adapter logger-name="JmsLogger" expression="'JMS message with operation ['+headers['operation']+'] created in DB'"/>
</chain>
我的问题如下,有时,由于没有明显的原因,日志中没有任何错误消息,我的消息不再被处理。如果轮询器停止工作,则不再调用链ID jmsMessageCreate。 如果服务器重新启动,它会再次运行良好,但我丢失了在轮询器停止和服务器重新启动之间发送的JMS消息。
我真的不知道在哪里寻找或做些什么来防止这种情况。可能是配置中的更改?
提前感谢您的帮助。
答案 0 :(得分:1)
轮询器线程很可能在代码中某处“卡住”。使用jstack <pid>
进行线程转储以查看线程正在执行的操作。您可以使用jps
查找pid。
为避免丢失邮件,您应在邮件驱动的适配器上设置acknowledge="transacted"
- 在版本4.2中将其更改为默认为true
。
您不应该在此环境中使用QueueChannels和pollers - 线程由消息驱动的适配器管理。使用队列通道,即使使用事务处理会话,只要将消息放入队列,容器就会提交。