上下文:在JBoss EAP 6.2中运行的Spring 4.0.6应用程序。应用程序的一部分是JMS队列,在接收端,它的消息需要并行处理,否则许多消息需要很长时间。
Spring的JMS侦听器配置为并发10,并委托给具有10个线程的执行程序池(第一个问题:这种关系是否正确?)
<bean id="executor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="10" />
<property name="maxPoolSize" value="10" />
<property name="queueCapacity" value="20" />
</bean>
<jms:listener-container destination-resolver="jndiDestinationResolver" destination-type="queue" acknowledge="auto" connection-factory="jmsConnectionFactory" concurrency="10" task-executor="executor">
<jms:listener destination="java:jboss/exported/jms/queue/myQueue" ref="myMessageHandler"/>
</jms:listener-container>
在加载下,经常出现以下错误:
10:32:47,457 ERROR [org.hornetq.ra] (org.springframework.jms.listener.DefaultMessageListenerContainer#0-112) HQ154002: Could not create session: javax.jms.IllegalStateException: Only allowed one session per connection. See the J2EE spec, e.g. J2EE1.4 Section 6.6
at org.hornetq.ra.HornetQRASessionFactoryImpl.allocateConnection(HornetQRASessionFactoryImpl.java:811)
at org.hornetq.ra.HornetQRASessionFactoryImpl.createSession(HornetQRASessionFactoryImpl.java:465)
at org.springframework.jms.support.JmsAccessor.createSession(JmsAccessor.java:197) [spring-jms-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer.access$1400(DefaultMessageListenerContainer.java:119) [spring-jms-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.initResourcesIfNecessary(DefaultMessageListenerContainer.java:1122) [spring-jms-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1101) [spring-jms-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1094) [spring-jms-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:991) [spring-jms-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_60]
现在,我了解JMS规范禁止这样做。目前尚不清楚Spring是如何达到限制的。特别是,我检查了具有以下片段的DefaultMesageListenerContainer source:
1120 if (this.session == null && getCacheLevel() >= CACHE_SESSION) {
1121 updateRecoveryMarker();
1122 this.session = createSession(getSharedConnection());
1123 }
所以 Spring似乎尝试重用连接(参见第1122行)。配置中是否缺少某些内容使其执行此操作?
答案 0 :(得分:2)
我在尝试使用通用JMS RA时偶然发现了同样的问题。 最终使其正常工作的是在侦听器容器上配置缓存级别,将其设置为"NONE",以避免在现有连接上创建新会话。
将 cache =“none”添加到 jms:listener-container 应该可以为您的配置提供技巧。