Jms 使用DefaultMessageListenerContainer连接到WebSphere MQ抛出;“连接已关闭”;反复地

Jms 使用DefaultMessageListenerContainer连接到WebSphere MQ抛出;“连接已关闭”;反复地,jms,websphere,ibm-mq,spring-jms,Jms,Websphere,Ibm Mq,Spring Jms,我需要从运行在WebSphere AS 6.1应用服务器上的web应用程序连接到z/OS队列上的远程WebSphere MQ。在WebSphere AS上,我配置了QueueConnectionFactory和Queue(一个包含部分远程队列数据的对象),并将大多数设置设置为其默认值—我只需要设置队列名称、通道、主机、端口和传输类型(即客户端)。我使用JNDI查找将它们注入到以下Spring 3.2配置中: <jee:jndi-lookup id="destination" jnd

我需要从运行在WebSphere AS 6.1应用服务器上的web应用程序连接到z/OS队列上的远程WebSphere MQ。在WebSphere AS上,我配置了QueueConnectionFactory和Queue(一个包含部分远程队列数据的对象),并将大多数设置设置为其默认值—我只需要设置队列名称、通道、主机、端口和传输类型(即客户端)。我使用JNDI查找将它们注入到以下Spring 3.2配置中:

    <jee:jndi-lookup id="destination" jndi-name="MyMQQueue" expected-type="javax.jms.Queue" />

    <jee:jndi-lookup id="targetConnectionFactory" jndi-name="MyMQQCF" expected-type="javax.jms.QueueConnectionFactory" />

    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"
      p:connectionFactory-ref="targetConnectionFactory"
      p:defaultDestination-ref="destination" />

    <bean id="simpleMessageListener" class="my.own.SimpleMessageListener"/>

    <bean id="msgListenerContainer"
      class="org.springframework.jms.listener.DefaultMessageListenerContainer">
      <property name="connectionFactory" ref="targetConnectionFactory" />
      <property name="destination" ref="destination" />
      <property name="messageListener" ref="simpleMessageListener" />
      <property name="taskExecutor" ref="managedThreadsTaskExecutor" />
      <property name="receiveTimeout" value="5000" />
      <property name="recoveryInterval" value="5000" />
   </bean>

   <bean id="managedThreadsTaskExecutor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor">
      <property name="workManagerName" value="wm/default" />
   </bean>
但停止从队列中删除消息

深入研究Spring代码,我发现DefaultMessageListenerContainer上的设置

<property name="cacheLevel" value="0"/>

解决了这个问题,因为现在每次我发送消息时都会从队列中读取消息。但是,查看到WebSphere MQ的TCP流量,我发现MQCLOSE/MQOPEN命令会重复发送到它,如中所示:

这可能意味着连接会持续关闭并重新打开

是否有人能提出缓存无法正常工作的原因,以及是否有一种相对简单的方法来修改Spring代码(例如扩展DefaultMessageListenerContainer),或者在MQ队列连接工厂/队列上设置一些属性以使其正常工作

编辑:

进一步搜索互联网,我发现了以下链接

这似乎描述了Tomcat上发生的类似问题。解决方案是在DefaultMessageListenerContainer上设置某个exceptionListener。但是,尝试在WebSphere上执行此操作会引发异常“javax.jms.IllegalStateException:Method setExceptionListener not Allowed”。根本原因似乎是J2EE1.4规范禁止在JMS连接上调用setExceptionListener

似乎设置

<property name="cacheLevel" value="0"/>
)

我们可以看到,创建连接的调用和从连接创建会话的调用都不会生成TCP流量,TCP流量仅通过创建使用者(如果我理解正确,则被视为“轻量级操作”),尝试从队列接收消息并关闭使用者来生成

因此,连接似乎是从相应的池中获取的,并且会话以某种方式被“缓存”

因此,这里的缓存似乎是由应用服务器完成的,而不是由Spring进行缓存

<property name="cacheLevel" value="0"/>
protected boolean doReceiveAndExecute(
            Object invoker, Session session, MessageConsumer consumer, TransactionStatus status)