ActiveMQ抛出异常javax.jms.IllegalStateException: The Session is closed
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ActiveMQ抛出异常javax.jms.IllegalStateException: The Session is closed相关的知识,希望对你有一定的参考价值。
初始配置
- maven
1 <dependency> 2 <groupId>org.springframework</groupId> 3 <artifactId>spring-jms</artifactId> 4 <version>4.2.0.RELEASE</version> 5 </dependency> 6 <dependency> 7 <groupId>org.apache.activemq</groupId> 8 <artifactId>activemq-spring</artifactId> 9 <version>5.12.1</version> 10 </dependency>
- spring-jms.xml
1 <!-- ======================================= 消费者配置 ============================================--> 2 <!-- 持久化主题订阅者(保证订阅者重启后能获得丢失的消息)ActiveMQ 连接工厂 --> 3 <bean id="consumerConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> 4 <property name="brokerURL" value="${jms.broker.url}"/> 5 <!-- Durable订阅者必须设置ClientId --> 6 <!--<property name="clientID" value="${jms.client.id.prefix}"/>--> 7 <property name="redeliveryPolicy"> 8 <bean name="defaultRedeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy"> 9 <property name="maximumRedeliveries" value="10"/> 10 <property name="redeliveryDelay" value="60000"/> 11 </bean> 12 </property> 13 </bean> 14 15 <!-- 将Connection、Session和MessageProducer池化,这样可以大大的减少资源消耗 --> 16 <bean id="consumerPooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop"> 17 <property name="connectionFactory" ref="consumerConnectionFactory"/> 18 <property name="maxConnections" value="50"/> 19 </bean> 20 21 <!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory --> 22 <bean id="consumerCachingConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory"> 23 <!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory --> 24 <property name="targetConnectionFactory" ref="consumerPooledConnectionFactory"/> 25 </bean> 26 27 <jms:listener-container connection-factory="consumerCachingConnectionFactory" response-destination-type="queue" acknowledge="client" > 28 <jms:listener destination="${jms.queue.charge.name}" ref="chargeMessageListener" concurrency="50-100" /> 29 <jms:listener destination="${jms.queue.charge.dlq}" ref="chargeMsgDLQListener" concurrency="5"/> 31 </jms:listener-container> 32 33 <!-- 消息监听器 --> 34 <bean id="chargeMessageListener" class="com.virtual.api.jms.ChargeMessageListener"/> 35 <bean id="chargeMsgDLQListener" class="com.virtual.api.jms.ChargeMsgDLQListener"/>
问题
运行一段时间(30 - 60分钟)后系统抛出异常
016-03-15 20:03:10.060 [org.springframework.jms.listener.DefaultMessageListenerContainer#0-39] DEBUG org.springframework.jms.connection.CachingConnectionFactory:486 - Closing cached Session: PooledSession { ActiveMQSession {id=ID:api1-20027-1458039790166-1:1:59,started=false} [email protected] } 2016-03-15 20:03:10.060 [org.springframework.jms.listener.DefaultMessageListenerContainer#0-33] DEBUG org.springframework.jms.listener.DefaultMessageListenerContainer:860 - Setup of JMS message listener invoker failed - already recovered by other invoker javax.jms.IllegalStateException: The Consumer is closed at org.apache.activemq.ActiveMQMessageConsumer.checkClosed(ActiveMQMessageConsumer.java:870) ~[activemq-client-5.12.1.jar:5.12.1] at org.apache.activemq.ActiveMQMessageConsumer.receive(ActiveMQMessageConsumer.java:633) ~[activemq-client-5.12.1.jar:5.12.1] at org.apache.activemq.jms.pool.PooledMessageConsumer.receive(PooledMessageConsumer.java:67) ~[activemq-jms-pool-5.12.1.jar:5.12.1] at org.springframework.jms.connection.CachedMessageConsumer.receive(CachedMessageConsumer.java:82) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveMessage(AbstractPollingMessageListenerContainer.java:420) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:300) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:253) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1150) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1142) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1039) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at java.lang.Thread.run(Thread.java:745) [na:1.7.0_79] 2016-03-15 20:03:10.060 [org.springframework.jms.listener.DefaultMessageListenerContainer#2-30] DEBUG org.springframework.jms.connection.CachingConnectionFactory:486 - Closing cached Session: PooledSession { ActiveMQSession {id=ID:api1-20027-1458039790166-1:1:14,started=false} [email protected] } 2016-03-15 20:03:10.060 [org.springframework.jms.listener.DefaultMessageListenerContainer#0-42] DEBUG org.springframework.jms.connection.CachingConnectionFactory:486 - Closing cached Session: PooledSession { ActiveMQSession {id=ID:api1-20027-1458039790166-1:1:61,started=false} [email protected] } 2016-03-15 20:03:10.060 [org.springframework.jms.listener.DefaultMessageListenerContainer#2-14] DEBUG org.springframework.jms.connection.CachingConnectionFactory:486 - Closing cached Session: PooledSession { ActiveMQSession {id=ID:api1-20027-1458039790166-1:1:38,started=false} [email protected] } 2016-03-15 20:03:10.061 [org.springframework.jms.listener.DefaultMessageListenerContainer#0-6] DEBUG org.springframework.jms.connection.CachingConnectionFactory:486 - Closing cached Session: PooledSession { ActiveMQSession {id=ID:api1-20027-1458039790166-1:1:60,started=false} [email protected] } 2016-03-15 20:03:10.061 [org.springframework.jms.listener.DefaultMessageListenerContainer#2-12] DEBUG org.springframework.jms.connection.CachingConnectionFactory:486 - Closing cached Session: PooledSession { ActiveMQSession {id=ID:api1-20027-1458039790166-1:1:42,started=false} [email protected] } 2016-03-15 20:03:10.061 [org.springframework.jms.listener.DefaultMessageListenerContainer#0-44] DEBUG org.springframework.jms.connection.CachingConnectionFactory:486 - Closing cached Session: PooledSession { ActiveMQSession {id=ID:api1-20027-1458039790166-1:1:62,started=false} [email protected] } 2016-03-15 20:03:10.061 [org.springframework.jms.listener.DefaultMessageListenerContainer#0-50] DEBUG org.springframework.jms.listener.DefaultMessageListenerContainer:860 - Setup of JMS message listener invoker failed - already recovered by other invoker javax.jms.IllegalStateException: The Consumer is closed at org.apache.activemq.ActiveMQMessageConsumer.checkClosed(ActiveMQMessageConsumer.java:870) ~[activemq-client-5.12.1.jar:5.12.1] at org.apache.activemq.ActiveMQMessageConsumer.receive(ActiveMQMessageConsumer.java:633) ~[activemq-client-5.12.1.jar:5.12.1] at org.apache.activemq.jms.pool.PooledMessageConsumer.receive(PooledMessageConsumer.java:67) ~[activemq-jms-pool-5.12.1.jar:5.12.1] at org.springframework.jms.connection.CachedMessageConsumer.receive(CachedMessageConsumer.java:82) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveMessage(AbstractPollingMessageListenerContainer.java:420) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:300) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:253) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1150) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1142) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1039) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at java.lang.Thread.run(Thread.java:745) [na:1.7.0_79] 2016-03-15 20:03:10.061 [org.springframework.jms.listener.DefaultMessageListenerContainer#0-1] DEBUG org.springframework.jms.listener.DefaultMessageListenerContainer:860 - Setup of JMS message listener invoker failed - already recovered by other invoker javax.jms.IllegalStateException: The Session is closed at org.apache.activemq.ActiveMQSession.checkClosed(ActiveMQSession.java:775) ~[activemq-client-5.12.1.jar:5.12.1] at org.apache.activemq.ActiveMQSession.getTransacted(ActiveMQSession.java:540) ~[activemq-client-5.12.1.jar:5.12.1] at org.apache.activemq.jms.pool.PooledSession.getTransacted(PooledSession.java:260) ~[activemq-jms-pool-5.12.1.jar:5.12.1] at sun.reflect.GeneratedMethodAccessor51.invoke(Unknown Source) ~[na:na] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_79] at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_79] at org.springframework.jms.connection.CachingConnectionFactory$CachedSessionInvocationHandler.invoke(CachingConnectionFactory.java:386) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at com.sun.proxy.$Proxy68.getTransacted(Unknown Source) ~[na:na] at org.springframework.jms.listener.AbstractMessageListenerContainer.commitIfNecessary(AbstractMessageListenerContainer.java:757) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:348) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:253) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1150) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1142) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1039) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at java.lang.Thread.run(Thread.java:745) [na:1.7.0_79] 2016-03-15 20:03:10.061 [org.springframework.jms.listener.DefaultMessageListenerContainer#0-13] DEBUG org.springframework.jms.listener.DefaultMessageListenerContainer:860 - Setup of JMS message listener invoker failed - already recovered by other invoker javax.jms.IllegalStateException: The Session is closed at org.apache.activemq.ActiveMQSession.checkClosed(ActiveMQSession.java:775) ~[activemq-client-5.12.1.jar:5.12.1] at org.apache.activemq.ActiveMQSession.getTransacted(ActiveMQSession.java:540) ~[activemq-client-5.12.1.jar:5.12.1] at org.apache.activemq.jms.pool.PooledSession.getTransacted(PooledSession.java:260) ~[activemq-jms-pool-5.12.1.jar:5.12.1] at sun.reflect.GeneratedMethodAccessor51.invoke(Unknown Source) ~[na:na] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_79] at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_79] at org.springframework.jms.connection.CachingConnectionFactory$CachedSessionInvocationHandler.invoke(CachingConnectionFactory.java:386) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at com.sun.proxy.$Proxy68.getTransacted(Unknown Source) ~[na:na] at org.springframework.jms.listener.AbstractMessageListenerContainer.commitIfNecessary(AbstractMessageListenerContainer.java:757) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:348) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:253) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1150) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1142) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1039) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at java.lang.Thread.run(Thread.java:745) [na:1.7.0_79] 2016-03-15 20:03:10.061 [org.springframework.jms.listener.DefaultMessageListenerContainer#0-19] DEBUG org.springframework.jms.listener.DefaultMessageListenerContainer:860 - Setup of JMS message listener invoker failed - already recovered by other invoker javax.jms.IllegalStateException: The Consumer is closed at org.apache.activemq.ActiveMQMessageConsumer.checkClosed(ActiveMQMessageConsumer.java:870) ~[activemq-client-5.12.1.jar:5.12.1] at org.apache.activemq.ActiveMQMessageConsumer.receive(ActiveMQMessageConsumer.java:633) ~[activemq-client-5.12.1.jar:5.12.1] at org.apache.activemq.jms.pool.PooledMessageConsumer.receive(PooledMessageConsumer.java:67) ~[activemq-jms-pool-5.12.1.jar:5.12.1] at org.springframework.jms.connection.CachedMessageConsumer.receive(CachedMessageConsumer.java:82) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveMessage(AbstractPollingMessageListenerContainer.java:420) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:300) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:253) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1150) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1142) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1039) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at java.lang.Thread.run(Thread.java:745) [na:1.7.0_79] 2016-03-15 20:03:10.061 [org.springframework.jms.listener.DefaultMessageListenerContainer#0-25] DEBUG org.springframework.jms.listener.DefaultMessageListenerContainer:860 - Setup of JMS message listener invoker failed - already recovered by other invoker javax.jms.IllegalStateException: The Consumer is closed at org.apache.activemq.ActiveMQMessageConsumer.checkClosed(ActiveMQMessageConsumer.java:870) ~[activemq-client-5.12.1.jar:5.12.1] at org.apache.activemq.ActiveMQMessageConsumer.receive(ActiveMQMessageConsumer.java:633) ~[activemq-client-5.12.1.jar:5.12.1] at org.apache.activemq.jms.pool.PooledMessageConsumer.receive(PooledMessageConsumer.java:67) ~[activemq-jms-pool-5.12.1.jar:5.12.1] at org.springframework.jms.connection.CachedMessageConsumer.receive(CachedMessageConsumer.java:82) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveMessage(AbstractPollingMessageListenerContainer.java:420) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:300) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:253) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1150) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1142) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1039) ~[spring-jms-4.2.0.RELEASE.jar:4.2.0.RELEASE] at java.lang.Thread.run(Thread.java:745) [na:1.7.0_79] 2016-03-15 20:03:10.061 [org.springframework.jms.listener.DefaultMessageListenerContainer#2-13] DEBUG org.springframework.jms.connection.CachingConnectionFactory:486 - Closing cached Session: PooledSession { ActiveMQSession {id=ID:api1-20027-1458039790166-1:1:41,started=false} [email protected] }
解决过程
- 搜索"activemq the session is closed", 得到第一个结果 stackoverflow, 答案里的activemq版本是5.8, 这问题在5.7, 5.8里是个bug, 我使用的是5.12, 但我还是加上了配置. 结果还是报错.
1 <!-- 将Connection、Session和MessageProducer池化,这样可以大大的减少资源消耗 --> 2 <bean id="consumerPooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop"> 3 <property name="connectionFactory" ref="consumerConnectionFactory"/> 4 <property name="maxConnections" value="50"/> 5 <property name="idleTimeout" value="0"/> 6 </bean>
- 查看activemq官网关于连接池的使用
1 <!-- a pooling based JMS provider --> 2 <bean id="jmsFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop"> 3 <property name="connectionFactory"> 4 <bean class="org.apache.activemq.ActiveMQConnectionFactory"> 5 <property name="brokerURL"> 6 <value>tcp://localhost:61616</value> 7 </property> 8 </bean> 9 </property> 10 </bean> 11 12 <!-- Spring JMS Template --> 13 <bean id="myJmsTemplate" class="org.springframework.jms.core.JmsTemplate"> 14 <property name="connectionFactory"> 15 <ref local="jmsFactory"/> 16 </property> 17 </bean>
- JmsTemplate直接使用PooledConnectionFactory
1 <!-- ======================================= 生产者配置 ============================================--> 2 <!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供--> 3 <bean id="producerConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> 4 <property name="brokerURL" value="${jms.broker.url}"/> 5 <property name="useAsyncSend" value="true"/> 6 <!-- clinetIDPrefix属性, 符合此前缀规则的consumer将成为该TOPIC的持久订阅者, 才可以获得此消息 --> 7 <!--<property name="clientIDPrefix" value="${jms.client.id.prefix}"/>--> 8 </bean> 9 10 <!-- 将Connection、Session和MessageProducer池化,这样可以大大的减少资源消耗 --> 11 <bean id="producerPooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop"> 12 <property name="connectionFactory" ref="producerConnectionFactory"/> 13 <property name="maxConnections" value="30"/> 14 </bean> 15 16 <!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 --> 17 <bean id="defaultJmsTemplate" class="org.springframework.jms.core.JmsTemplate"> 18 <!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 --> 19 <property name="connectionFactory" ref="producerPooledConnectionFactory"/> 20 <!-- 使 deliveryMode, priority, timeToLive设置生效--> 21 <property name="explicitQosEnabled" value="true"/> 22 <!-- 设置NON_PERSISTENT模式, 默认为PERSISTENT --> 23 <property name="deliveryPersistent" value="true"/> 24 <!-- 设置优先级0-9, 默认为4 --> 25 <property name="priority" value="4"/> 26 </bean>
- 不使用PooledConnectionFactory, JmsTemplate直接使用CachingConnectionFactory(同时增加配置项)
1 <!-- ======================================= 生产者配置 ============================================--> 2 <!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供--> 3 <bean id="producerConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> 4 <property name="brokerURL" value="${jms.broker.url}"/> 5 <property name="useAsyncSend" value="true"/> 6 <!-- clinetIDPrefix属性, 符合此前缀规则的consumer将成为该TOPIC的持久订阅者, 才可以获得此消息 --> 7 <!--<property name="clientIDPrefix" value="${jms.client.id.prefix}"/>--> 8 </bean> 9 10 <!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory --> 11 <bean id="producerCachingConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory"> 12 <!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory --> 13 <property name="targetConnectionFactory" ref="producerConnectionFactory"/> 14 <property name="reconnectOnException" value="true"/> 15 <property name="cacheConsumers" value="false"/> 16 <property name="cacheProducers" value="false"/> 17 <property name="sessionCacheSize" value="50"/> 18 </bean> 19 20 <!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 --> 21 <bean id="defaultJmsTemplate" class="org.springframework.jms.core.JmsTemplate"> 22 <!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 --> 23 <property name="connectionFactory" ref="producerCachingConnectionFactory"/> 24 <!-- 使 deliveryMode, priority, timeToLive设置生效--> 25 <property name="explicitQosEnabled" value="true"/> 26 <!-- 设置NON_PERSISTENT模式, 默认为PERSISTENT --> 27 <property name="deliveryPersistent" value="true"/> 28 <!-- 设置优先级0-9, 默认为4 --> 29 <property name="priority" value="4"/> 30 </bean>
- 只为CachingConnectionFactory增加配置项
1 <!-- ======================================= 生产者配置 ============================================--> 2 <!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供--> 3 <bean id="producerConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> 4 <property name="brokerURL" value="${jms.broker.url}"/> 5 <property name="useAsyncSend" value="true"/> 6 <!-- clinetIDPrefix属性, 符合此前缀规则的consumer将成为该TOPIC的持久订阅者, 才可以获得此消息 --> 7 <!--<property name="clientIDPrefix" value="${jms.client.id.prefix}"/>--> 8 </bean> 9 10 <!-- 将Connection、Session和MessageProducer池化,这样可以大大的减少资源消耗 --> 11 <bean id="producerPooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop"> 12 <property name="connectionFactory" ref="producerConnectionFactory"/> 13 <property name="maxConnections" value="30"/> 14 </bean> 15 16 <!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory --> 17 <bean id="producerCachingConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory"> 18 <!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory --> 19 <property name="targetConnectionFactory" ref="producerConnectionFactory"/> 20 <property name="reconnectOnException" value="true"/> 21 <property name="cacheConsumers" value="false"/> 22 <property name="cacheProducers" value="false"/> 23 <property name="sessionCacheSize" value="50"/> 24 </bean> 25 26 <!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 --> 27 <bean id="defaultJmsTemplate" class="org.springframework.jms.core.JmsTemplate"> 28 <!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 --> 29 <property name="connectionFactory" ref="producerCachingConnectionFactory"/> 30 <!-- 使 deliveryMode, priority, timeToLive设置生效--> 31 <property name="explicitQosEnabled" value="true"/> 32 <!-- 设置NON_PERSISTENT模式, 默认为PERSISTENT --> 33 <property name="deliveryPersistent" value="true"/> 34 <!-- 设置优先级0-9, 默认为4 --> 35 <property name="priority" value="4"/> 36 </bean>
测试结果
- 依然会抛出异常, 但会自动回复连接
2016-03-16 14:16:17.036 [org.springframework.jms.listener.DefaultMessageListenerContainer#0-13] WARN org.springframework.jms.listener.DefaultMessageListenerContainer:871 - Setup of JMS message listener invoker failed for destination ‘q.virtual.charge‘ - trying to recover. Cause: The Consumer is closed 2016-03-16 14:16:17.051 [org.springframework.jms.listener.DefaultMessageListenerContainer#1-1] WARN org.springframework.jms.listener.DefaultMessageListenerContainer:871 - Setup of JMS message listener invoker failed for destination ‘DLQ.q.virtual.charge‘ - trying to recover. Cause: The Consumer is closed 2016-03-16 14:16:17.055 [org.springframework.jms.listener.DefaultMessageListenerContainer#2-1] WARN org.springframework.jms.listener.DefaultMessageListenerContainer:871 - Setup of JMS message listener invoker failed for destination ‘q.virtual.retry.charge‘ - trying to recover. Cause: The Consumer is closed 2016-03-16 14:16:17.056 [ActiveMQ Task-1] INFO org.apache.activemq.transport.failover.FailoverTransport:1068 - Successfully connected to tcp://xxxx:61616 2016-03-16 14:16:17.056 [ActiveMQ Task-1] INFO org.apache.activemq.transport.failover.FailoverTransport:1068 - Successfully connected to tcp://xxx:61616 2016-03-16 14:16:17.065 [org.springframework.jms.listener.DefaultMessageListenerContainer#1-1] INFO org.springframework.jms.listener.DefaultMessageListenerContainer:921 - Successfully refreshed JMS Connection 2016-03-16 14:16:17.065 [org.springframework.jms.listener.DefaultMessageListenerContainer#0-13] INFO org.springframework.jms.listener.DefaultMessageListenerContainer:921 - Successfully refreshed JMS Connection 2016-03-16 14:16:17.079 [ActiveMQ Task-1] INFO org.apache.activemq.transport.failover.FailoverTransport:1068 - Successfully connected to tcp://172.17.4.101:61616 2016-03-16 14:16:17.086 [org.springframework.jms.listener.DefaultMessageListenerContainer#2-1] INFO org.springframework.jms.listener.DefaultMessageListenerContainer:921 - Successfully refreshed JMS Connection
- 完全没有异常信息
- 错误依旧
结论
最终的配置文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:amq="http://activemq.apache.org/schema/core" 4 xmlns:jms="http://www.springframework.org/schema/jms" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 重新传递 Mule ESB 处理的失败的 activemq jms 消息时保留异常原因