Websphere 7 + Websphere MQ 7.X + Spring Integration + JMS - 消息侦听器停止从Queue读取消息

Rah*_*wal 5 spring-integration spring-jms ibm-mq

我们正在使用JMS和Spring Integration从Websphere MQ读取消息.

<task:executor id="demoMessageReceiverChannelTE" pool-size="1-3" queue-capacity="5" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<int:channel id="demoMessageReceiverChannel">
    <int:dispatcher task-executor="demoMessageReceiverChannelTE"/>
    <int:interceptors>
        <int:ref bean="messageReceiverInterceptor" />
    </int:interceptors>
</int:channel>

<jms:message-driven-channel-adapter
id="demoMesssageReceiverAdapter" channel="demoMessageReceiverChannel"
connection-factory="srcJmsConnectionFactory" destination="srcReceiverQueue"
error-channel="errorChannel" message-converter="demoIncomingMessageConverter"
transaction-manager="srcJmsTransactionManager" send-timeout="65000"
header-mapper="demoJmsHeaders" />
Run Code Online (Sandbox Code Playgroud)

还有另一个系统,它将消息放在此队列上.(超出我们的范围)

我们可以在队列中一次读取2000条消息.

有时,Message Listener会停止从Queue读取消息,当我尝试解决此问题时,它会说明队列中有一些未提交的消息,哪个侦听器尝试读取并且无法进一步处理并自行挂起.

当从队列中手动删除该消息时,它会完美地处理其他消息.

那么如何跳过这些未提交的消息,以便系统可以继续下一条消息呢?

T.R*_*Rob 4

听起来像是一个经典的未处理的有毒消息问题。当应用程序读取它无法处理的消息时,该消息将被退回到队列中。然后再次读回它,因为它位于队列的顶部。这会导致消息看起来处于同步点之下,直到最后侦听器放弃并停止。

有时问题出在应用程序中,并且是应用程序显式调用ROLLBACK. 有时,回滚发生在应用程序甚至看到消息之前。例如,如果消息无法转换为本地代码页,或其他低级错误。

如果发生这种情况,答案是定义一个回退队列,然后更改输入队列以指向它。例如,如果调用输入队列,SRC.RECEIVER.QUEUE您可以使用以下命令在 QMgr 上执行类似的操作runmqsc

DEFINE QL(SRC.RECEIVER.QUEUE.BKOUT)
ALTER QL(SRC.RECEIVER.QUEUE) BOQNAME(SRC.RECEIVER.QUEUE.BKOUT) BOTHRESH(15)
Run Code Online (Sandbox Code Playgroud)

如果问题确实是有害消息,则问题消息将作为未提交的消息显示在回退队列中。一旦应用程序COMMIT针对源队列发出下一个消息,回退消息将在回退队列中变得可见。如果没有其他消息到达源队列,则有害消息将在回退队列中保持未提交状态,或者在ROLLBACK由应用程序或 QMgr 调用时可能恢复到源队列。

回退队列的设置很简单,并且应该是标准做法,因此无论是否解决问题,我都建议这样做。请参阅信息中心的处理 JMS 的 WebSphere MQ 类中的有害消息。