弹簧集成轮询器在一段时间后挂起或停止
我有一个应用程序读取来自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消息。
我真的不知道在哪里看或做什么来防止这种情况。也许改变配置?
在此先感谢您的帮助。
最有可能的是,轮询线程“卡在”代码中的某处。使用jstack <pid>
进行线程转储以查看线程正在执行的操作。您可以使用jps
来查找pid。
为避免丢失消息,您应该在消息驱动的适配器上设置acknowledge="transacted"
- 在版本4.2中将其更改为默认为true
。
在此环境中,您不应该使用QueueChannel和轮询器 - 线程由消息驱动的适配器管理。使用队列通道,即使是事务处理会话,容器也会在消息放入队列后立即提交。
感谢您的帮助。我删除了轮询器,并按照您的建议设置了确认选项。我的本地环境似乎一切顺利。 问题发生在我无法访问的生产环境中,因此我无法运行jstack :(我会看看它是否会再次发生。 – Mannekenpix
这可能是一个堆问题?面对它一个...使用visualvm或类似的方式检查应用程序。 –
您不应该使用带有消息驱动适配器的队列通道和轮询器 - 请参阅我的答案。 –