Spring 集成 jms 消息驱动的通道适配器失败

Spring Integration jms message driven channel adapter fails

我正在使用 spring 集成 4.1.0 使用 jms-int:message-driven-channel-adapter

实现来自 TIBCO EMS 队列的消息消费

我有 9 个不同的消息驱动通道适配器在不同队列中的不同服务器上侦听。

下面是消息驱动通道适配器的定义方式

<int-jms:message-driven-channel-adapter
        id="mdca1" connection-factory="connectionFactory1"
        channel="jmsChannel1" destination="queueName1"
        error-channel="errorChannel" max-concurrent-consumers="5" auto-startup="true"/>

<int-jms:message-driven-channel-adapter
        id="mdca2" connection-factory="connectionFactory2"
        channel="jmsChannel2" destination="queueName2"
        error-channel="errorChannel" max-concurrent-consumers="5" auto-startup="true"/>

<bean id="connectionFactory1" class="org.springframework.jms.connection.CachingConnectionFactory">
    <property name="targetConnectionFactory" ref="tcf1"/>
    <property name="sessionCacheSize" value="${sessionCacheSize}"/>
    <property name="cacheProducers" value="${cacheProducers}"/>
    <property name="cacheConsumers" value="${cacheConsumers}"/>
</bean>
<bean id="tcf1" class="${connectionFactoryClassName}">
        <property name="serverUrl" value="${serverUrl1}" />
        <property name="userName" value="${username1}" />
        <property name="userPassword" value="${password1}" />
    </bean>

<bean id="connectionFactory2" class="org.springframework.jms.connection.CachingConnectionFactory">
    <property name="targetConnectionFactory" ref="tcf2"/>
    <property name="sessionCacheSize" value="${sessionCacheSize}"/>
    <property name="cacheProducers" value="${cacheProducers}"/>
    <property name="cacheConsumers" value="${cacheConsumers}"/>
</bean>
<bean id="tcf2" class="${connectionFactoryClassName}">
        <property name="serverUrl" value="${serverUrl2}" />
        <property name="userName" value="${username2}" />
        <property name="userPassword" value="${password2}" />
    </bean>

我在 Tomcat 上部署了我的应用程序,一切正常。所有适配器从队列中读取消息并发送以供处理。

但由于某种原因,过了一段时间后,消息并没有从队列中提取出来。目前我必须重新启动 tomcat 才能让适配器再次工作。 我在 UI 到 start/stop 适配器中有一个按钮,但是一旦适配器停止从队列中选取消息,它就不起作用了。 Start/Stop 按钮在适配器选择消息时也能正常工作。我可以停止,适配器停止接收消息,我可以启动,适配器开始接收消息。问题是当我有我的适配器 运行 一段时间后,比如 5 - 10 小时后,队列中有一条消息,即使适配器处于 运行 状态,它也没有选择。然后按钮也停止工作。

任何人都可以帮助解决问题吗?为什么适配器会在特定时间(例如 5-10 小时)后出现故障?

非常感谢任何帮助。

更新: 这是侦听器失败时来自 jstack 的堆栈跟踪。

"TIBCO EMS TCPLink Reader (Server-15108908)" daemon prio=10 tid=0x00007f1874115000 nid=0xc8f runnable [0x00007f18b2f1d000]
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:152)
    at java.net.SocketInputStream.read(SocketInputStream.java:122)
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:254)
    - locked <0x00000006c2d8ea68> (a java.io.BufferedInputStream)
    at java.io.DataInputStream.readInt(DataInputStream.java:387)
    at com.tibco.tibjms.TibjmsxLinkTcp._readWireMsg(TibjmsxLinkTcp.java:625)
    at com.tibco.tibjms.TibjmsxLinkTcp$LinkReader.work(TibjmsxLinkTcp.java:280)
    at com.tibco.tibjms.TibjmsxLinkTcp$LinkReader.run(TibjmsxLinkTcp.java:259)

"org.springframework.jms.listener.DefaultMessageListenerContainer#1-5" prio=10 tid=0x00000000019de000 nid=0xc8e in Object.wait() [0x00007f18b301e000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000006c2eabdf8> (a java.lang.Object)
    at com.tibco.tibjms.TibjmsxSessionImp._getSyncMessage(TibjmsxSessionImp.java:2288)
    at com.tibco.tibjms.TibjmsxSessionImp._receive(TibjmsxSessionImp.java:2122)
    - locked <0x00000006c2eabdf8> (a java.lang.Object)
    at com.tibco.tibjms.TibjmsMessageConsumer._receive(TibjmsMessageConsumer.java:276)
    at com.tibco.tibjms.TibjmsMessageConsumer.receive(TibjmsMessageConsumer.java:481)
    at        org.springframework.jms.connection.CachedMessageConsumer.receive(CachedMessageConsumer.java:82)
    at   org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveMessage(AbstractPollingMessageListenerContainer.java:413)
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:293)
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:246)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1142)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1134)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1031)
    at java.lang.Thread.run(Thread.java:745)

"org.springframework.jms.listener.DefaultMessageListenerContainer#3-2" prio=10 tid=0x00007f18ac001000 nid=0xc8d in Object.wait() [0x00007f18b311f000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000006c2e30270> (a java.lang.Object)
    at com.tibco.tibjms.TibjmsxSessionImp._getSyncMessage(TibjmsxSessionImp.java:2288)
    at com.tibco.tibjms.TibjmsxSessionImp._receive(TibjmsxSessionImp.java:2122)
    - locked <0x00000006c2e30270> (a java.lang.Object)
    at com.tibco.tibjms.TibjmsMessageConsumer._receive(TibjmsMessageConsumer.java:276)
    at com.tibco.tibjms.TibjmsMessageConsumer.receive(TibjmsMessageConsumer.java:481)
    at org.springframework.jms.connection.CachedMessageConsumer.receive(CachedMessageConsumer.java:82)
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveMessage(AbstractPollingMessageListenerContainer.java:413)
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:293)
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:246)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1142)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1134)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1031)
    at java.lang.Thread.run(Thread.java:745)

有意见吗?

这一般是由于下游流程中的某些组件不间断地挂起容器线程(例如从没有超时的套接字读取,没有数据到达)造成的。

要进行诊断,请在发生挂起时进行线程转储(例如 jstack ),以找出侦听器容器线程在做什么。