2014-10-19 2 views
1

컨텍스트 : JBoss EAP 6.2에서 실행되는 Spring 4.0.6 응용 프로그램. 응용 프로그램의 일부는 JMS 대기열이며 수신 측에서는 메시지를 병렬로 처리해야합니다. 그렇지 않으면 많은 메시지가 너무 오래 걸립니다.Spring/HornetQ : HQ154002 : 세션을 만들 수 없습니다 : 연결 당 하나의 세션 만 허용됩니다.

봄의 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 스펙이이를 금지하고 있음을 이해합니다. 스프링이 한계에 부딪치게되는 방법이 명확하지 않습니다.

1120 if (this.session == null && getCacheLevel() >= CACHE_SESSION) { 
1121  updateRecoveryMarker(); 
1122  this.session = createSession(getSharedConnection()); 
1123 } 

그렇게 봄이 연결을 (라인 (1122) 참조) 재사용을 시도 나타납니다 특히, 나는 다음과 같은 조각이있는 DefaultMesageListenerContainer source를 확인했습니다. 이 작업을 수행하는 구성에서 누락 된 것이 있습니까?

+0

당신의'jmsConnectionFactory'는 어떻게 생겼습니까? –

+0

@ StéphaneNicoll 여기에 있습니다 : wishihadabettername

+0

여기서 명백하게 잘못된 것을 보지 마라. 문제를 재현하는 프로젝트를 공유 할 수 있습니까? –

답변

2

일반 JMS RA를 사용하려고 할 때 동일한 문제가 발생했습니다. 결국 제대로 작동하게 만들었던 이유는 청크 컨테이너의 캐시 레벨을 "NONE"으로 설정하여 기존 연결에서 새 세션을 만들지 않기 위해서였습니다. 당신의 JMS에

추가 캐시 = "없음" : 리스너 컨테이너은 사용자 구성에 맞게 트릭을해야한다.

+1

아니면 XML 대신 자바 설정을 사용한다면, DefultMessageListnerContainer의 인스턴스에서 이것을 호출 할 수 있습니다 :'setCacheLevel (DefaultMessageListenerContainer.CACHE_NONE)' – ToeBee