2013-04-11 3 views
0

어쩌면 어리석은 질문 일 수 있습니다. 매우 간단한 것이 빠졌지 만, 정말 붙어 있습니다. 내가 ActiveMQ를 5.5.1 및 SI 2.1.4spring-jms OutboundGateway가 답장을받지 못합니다.

내 CONFIGS 조각 사용하고 있습니다 :

--- 서버를 ---

<beans:bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> 
    <beans:property name="brokerURL" value="tcp://localhost:61616" /> 
</beans:bean> 


    <beans:bean id="listQueue" class="org.apache.activemq.command.ActiveMQQueue"> 
     <beans:constructor-arg name="name" value="LIST_QUEUE"/> 
    </beans:bean> 

    <beans:bean id="replyListQueue" class="org.apache.activemq.command.ActiveMQQueue"> 
     <beans:constructor-arg name="name" value="REPLY_LIST_QUEUE"/> 
    </beans:bean>    

    <channel id="replyListChannel"/> 
    <channel id="listIn" /> 
    <channel id="listDriver"/> 
    <channel id="listStock"/>  


    <jms:inbound-channel-adapter id="listInJms" 
     connection-factory="connectionFactory" 
     destination="listQueue" 
     channel="listIn"   
     auto-startup="true"> 
     <poller fixed-rate="3000"/> 
    </jms:inbound-channel-adapter> 



    <header-value-router input-channel="listIn" header-name="List" 
      default-output-channel="nullChannel">   
     <mapping value="Driver" channel="listDriver" /> 
     <mapping value="Stock" channel="listStock" /> 
    </header-value-router> 

    <jms:outbound-channel-adapter connection-factory="connectionFactory" 
     channel="replyListChannel" 
     destination="replyListQueue" 
     auto-startup="true">     
    </jms:outbound-channel-adapter> 

--- CLIENT ---

<beans:bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> 
    <beans:property name="brokerURL" value="tcp://localhost:61616" /> 
</beans:bean>  

<beans:bean id="requestListQueue" class="org.apache.activemq.command.ActiveMQQueue"> 
    <beans:constructor-arg value="LIST_QUEUE"/> 
</beans:bean>   

<beans:bean id="replyListQueue" class="org.apache.activemq.command.ActiveMQQueue"> 
    <beans:constructor-arg value="REPLY_LIST_QUEUE"/> 
</beans:bean> 


<channel id="requestListChannel"> 
    <queue capacity="20"/> 
</channel> 

<channel id="listStockChannel"> 
    <queue capacity="20"/> 
</channel> 

<channel id="listDriverChannel"> 
    <queue capacity="20"/> 
</channel>  

<channel id="replyListChannel"/>     

<jms:outbound-gateway id="outListGW" 
    connection-factory="connectionFactory" 
    request-destination="requestListQueue" 
    request-channel="requestListChannel" 
    reply-destination="replyListQueue" 
    reply-channel="replyListChannel" 
    reply-timeout="20000" 
    receive-timeout="20000"> 
    <poller fixed-rate="5000" /> 
</jms:outbound-gateway>  


<header-value-router input-channel="replyListChannel" header-name="List" 
     default-output-channel="nullChannel">   
    <mapping value="Driver" channel="listDriverChannel" /> 
    <mapping value="Stock" channel="listStockChannel" /> 
</header-value-router> 

다음 코드에서 어떤 장소에 내가 수동으로 요청을하고 응답 채널을 청취 :

public static DriverList requestDriverList() { 

    Message<String> ldrm = MessageBuilder.withPayload("DriverList request"). 
      setHeader("List", "Driver").build();    
    try { 
     ApplicationContext ctx = 
     new ClassPathXmlApplicationContext("classpath:dmclnt/config/integ-context.xml"); 
     MessageChannel requestListChannel = 
       ctx.getBean("requestListChannel", MessageChannel.class); 
     QueueChannel listDriverChannel = 
       ctx.getBean("listDriverChannel", QueueChannel.class); 


     logger.info("Request for DriverList is sent to channel"); 

     Message dlm = listDriverChannel.receive(20000); 

     String xmlDL = (String)dlm.getPayload(); 

     JAXBContext jaxbctx = JAXBContext.newInstance(DriverList.class); 
     DriverList dl = (DriverList)jaxbctx.createUnmarshaller(). 
     unmarshal(newStringReader(xmlDL)); 
     logger.info("DriverList objct unmarshalled: "+dl.toString()); 
     return dl;    
    } catch (JAXBException e) { 
     logger.error("Error converting xmlDriverList to DriverList object",e); 
     return null; 
    } catch (RuntimeException e){ 
     logger.error(e); 
     return null; 
    } 
} 
01 23,516,

는하지만 모든 시간을

"MessageTimeoutException: failed to receive JMS response within timeout of: 20000ms" 

을받을 수 있습니다. 서버 로그를 살펴보면 정확한 페이로드가 포함 된 응답이 서버에서 클라이언트로 성공적으로 전송되었음을 알 수 있으며 또한 응답은 ActiveMQ 관리 콘솔에서 볼 수 있듯이 REPLY_LIST_QUEUE에 배치됩니다. 그리고 더 이상 아무것도 일어나지 않습니다! REPLY_LIST_QUEUE의 메시지 With_Correct_Payload은이 대기열의 대기 중 및 대기열에 포함 된 상태에 있습니다. 메시지가 대기열에서 제외됩니다. JmsOutboundGateway는 receive-timeout = "20000ms"지연이 회신을받는 데 충분하지 않더라도 reply-queue에서 메시지를 선택하지 않는 것으로 보입니다. 내가 뭘 잘못하고 있니?

답변

1

아웃 바운드 게이트웨이에 메시지 상관 관계에 대한 기대가 있기 때문입니다. 귀하의 구성에 따라, 게이트웨이는 서버가 상관 ID의 인 Y 운드 메시지 ID를 리턴 할 것으로 기대합니다. 메시지 선택기를 사용하여 응답을받습니다.

서버에서 인바운드 게이트웨이를 사용하면 상관 관계가 처리됩니다.

인바운드 게이트웨이 대신 서버에서 개별 채널 어댑터를 사용하도록 선택한 특별한 이유가 있습니까?

2.2.3으로 이동하여 아웃 바운드 게이트웨이가 개선되었지만 서버에서 적절한 상관 관계가 필요한 경우를 고려할 수 있습니다. 편집

: 당신이 당신의 현재 구성과 함께, 대신 어댑터의 한 쌍을 사용하고자하는 경우 아래의 코멘트 당 ...

당신은 jms_correlationId에 인바운드 헤더를 jms_messageid를 복사 할 <header-enricher/>를 사용해야합니다.

또는 클라이언트 측 (아웃 바운드 게이트웨이)에서 correlation-key 특성을 JmsCorrelationId으로 설정하십시오. 이렇게하면 게이트웨이가 아웃 바운드 메시지의 해당 헤더를 채우게되고 서버 측에서 아무 것도 필요하지 않게됩니다.

+0

감사합니다. 게리, 답장을드립니다. – user1676178

+0

고마워, 게리, 답장을 보내고 매우 늦어서 고맙습니다. 여행 중이 었습니다. 실제로 문제가없는 것으로 나타났습니다. 인바운드 게이트웨이를 사용하지 않는 이유.하지만 나는 거기에 있다고 생각했습니다. :). 아웃 바운드 및 인바운드 게이트웨이로 모든 작업이 정상적으로 작동합니다.하지만 서버에 두 개의 개별 채널 어댑터 (인바운드 및 아웃 바운드)를 만들려는 이유가 있다면 서버에서 어떤 종류의 상관 관계를 만들 수 있습니까?setCorrelationId를 사용합니까? 예 : AFAIK, service-activator 사용 (예 : SI 메시지 작업, service-activator 사용 필요) JMS 헤더를 가져올 수 없습니까? – user1676178

+0

나는 내 대답을 업데이트했다. –

관련 문제