我们正在使用下面提到的spring integration jms入站网关来监听和读取来自mq的消息,处理它并回复到replyTo mq。
但是,我们在处理并发请求时一直在观察Session Close异常。据观察,很少有请求是坏的(即没有携带replyTo头),导致一些异常影响其他好请求的处理,即在发送回复时导致会话关闭异常。
<jms:inbound-gateway request-channel="inputChannel" error-channel="errorChannel"
container="channelContainer"/>
<bean id="channelContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="getQueue" />
<property name="concurrentConsumers" value="10" />
<property name="autoStartup" value="true" />
</bean>
看起来,Spring集成DMLC确实可以在任何异常的情况下恢复监听器设置失败。但是,对于并发请求而言,它似乎并不一致,也会影响好请求。
请建议。
注意 - 我已经尝试将exposeListenerSession的值设置为false,这似乎解决了给定的问题,但它看起来每次创建给定的资源而不管异常。
我更希望找到一些解决方案,只有在例外的情况下才能刷新或重新建立给定的资源。我们正在使用spring 3.1.2发行版和2.2.0版本的spring-integration。
下面是异常堆栈跟踪 -
[18-Mar-19 10:49:55,289] [org.springframework.jms.listener.DefaultMessageListenerContainer#0-20:INFO] [DefaultMessageListenerContainer:875]成功刷新JMS连接 [18-Mar-19 10:49:55,290] [org.springframework.jms.listener.DefaultMessageListenerContainer#0-17:DEBUG] [DefaultMessageListenerContainer:823] JMS消息监听器调用程序失败的设置 - 已被其他调用者恢复 javax.jms.InvalidDestinationException:无法确定回复目标:请求消息不包含回复目标,并且没有设置默认回复目标。 在org.springframework.integration.jms.ChannelPublishingJmsMessageListener.getReplyDestination(ChannelPublishingJmsMessageListener.java:361) 在org.springframework.integration.jms.ChannelPublishingJmsMessageListener.onMessage(ChannelPublishingJmsMessageListener.java:282) 在org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:537) 在org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:497) 在org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:468) 在org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:326) at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:264) at org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1071) at org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1063) 在org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:960) 在java.lang.Thread.run(Thread.java:798) [18-Mar-19 10:49:55,290] [org.springframework.jms.listener.DefaultMessageListenerContainer#0-16:DEBUG] [DefaultMessageListenerContainer:823] JMS消息监听器调用程序失败的设置 - 已被其他调用者恢复 com.ibm.msg.client.jms.DetailedIllegalStateException:JMSCC0032:此消息使用者已关闭。 称为方法的应用程序,在关闭消息使用者后不得使用该方法。 在调用方法之前,请确保未关闭消息使用者。 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:86) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:58) 在java.lang.reflect.Constructor.newInstance(Constructor.java:542) 在com.ibm.msg.client.commonservices.j2se.NLSServices.createException(NLSServices.java:314) 在com.ibm.msg.client.commonservices.nls.NLSServices.createException(NLSServices.java:228) at com.ibm.msg.client.jms.internal.JmsErrorUtils.createException(JmsErrorUtils.java:104) 在com.ibm.msg.client.jms.internal.State.checkNotClosed(State.java:145) at com.ibm.msg.client.jms.internal.JmsMessageConsumerImpl.receive(JmsMessageConsumerImpl.java:428) at com.ibm.mq.jms.MQMessageConsumer.receive(MQMessageConsumer.java:212) 在com.ibm.ejs.jms.JMSMessageConsumerHandle.receive(JMSMessageConsumerHandle.java:553) 在com.ibm.ejs.jms.JMSMessageConsumerHandle.receive(JMSMessageConsumerHandle.java:501) 在org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveMessage(AbstractPollingMessageListenerContainer.java:431) 在org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:311) at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:264) at org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1071) at org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1063) 在org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:960) 在java.lang.Thread.run(Thread.java:798) [18-Mar-19 10:49:55,290] [org.springframework.jms.listener.DefaultMessageListenerContainer#0-12:DEBUG] [DefaultMessageListenerContainer:823] JMS消息监听器调用程序的设置失败 - 已被其他调用程序恢复 com.ibm.msg.client.jms.DetailedIllegalStateException:JMSCC0032:此消息使用者已关闭。 称为方法的应用程序,在关闭消息使用者后不得使用该方法。 在调用方法之前,请确保未关闭消息使用者。 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:86) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:58) 在java.lang.reflect.Constructor.newInstance(Constructor.java:542) 在com.ibm.msg.client.commonservices.j2se.NLSServices.createException(NLSServices.java:314) 在com.ibm.msg.client.commonservices.nls.NLSServices.createException(NLSServices.java:228) at com.ibm.msg.client.jms.internal.JmsErrorUtils.createException(JmsErrorUtils.java:104) 在com.ibm.msg.client.jms.internal.State.checkNotClosed(State.java:145) at com.ibm.msg.client.jms.internal.JmsMessageConsumerImpl.receive(JmsMessageConsumerImpl.java:428) at com.ibm.mq.jms.MQMessageConsumer.receive(MQMessageConsumer.java:212) 在com.ibm.ejs.jms.JMSMessageConsumerHandle.receive(JMSMessageConsumerHandle.java:553) 在com.ibm.ejs.jms.JMSMessageConsumerHandle.receive(JMSMessageConsumerHandle.java:501) 在org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveMessage(AbstractPollingMessageListenerContainer.java:431) 在org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:311) at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:264) at org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1071) at org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1063) 在org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:960) 在java.lang.Thread.run(Thread.java:798) [18-Mar-19 10:49:55,290] [org.springframework.jms.listener.DefaultMessageListenerContainer#0-11:DEBUG] [DefaultMessageListenerContainer:823] JMS消息监听器调用程序的设置失败 - 已被其他调用程序恢复 javax.jms.IllegalStateException:会话已关闭 在com.ibm.ejs.jms.JMSSessionHandle.getOpenSession(JMSSessionHandle.java:1311) 在com.ibm.ejs.jms.JMSSessionHandle.getOpenUnifiedSession(JMSSessionHandle.java:1349) 在com.ibm.ejs.jms.JMSSessionHandle.getTransacted(JMSSessionHandle.java:617) at org.springframework.jms.listener.AbstractMessageListenerContainer.rollbackOnExceptionIfNecessary(AbstractMessageListenerContainer.java:605) 在org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:471) 在org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:326) at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:264) at org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1071) at org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1063) 在org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:960) 在java.lang.Thread.run(Thread.java:798)