0

たぶんそれはばかげた質問で、非常に単純なものが欠けていますが、本当に行き詰まっています。ActiveMQ 5.5.1 と SI 2.1.4 を使用しています

私の構成スニペット:

- -サーバ - -

    <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>

- -クライアント - -

<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;
    } 
}

しかし、私は受け取ります

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

いつも。サーバーログを見ると、正しいペイロードを含む応答がサーバーからクライアントに正常に送信され、さらに、ActiveMQ 管理コンソールで確認できるように、応答が REPLY_LIST_QUEUE に配置されていることがわかります。そして、それ以上何も起こりません!REPLY_LIST_QUEUE With_Correct_Payload のメッセージはこのキューで保留中およびエンキュー状態にあります。デキューされたメッセージはありません。receive-timeout="20000ms" の遅延が応答を得るのに十分すぎるにもかかわらず、JmsOutboundGateway は応答先キューからメッセージを取得しないようです。私は何を間違っていますか?

4

1 に答える 1

1

これは、アウトバウンド ゲートウェイがメッセージの相関に関して何らかの期待を持っているためです。あなたの設定では、ゲートウェイはサーバーが相関IDで受信メッセージIDを返すことを期待していると思います。メッセージセレクターを使用して応答を受信します。

サーバーで受信ゲートウェイを使用する場合は、相関が処理されます。

受信ゲートウェイの代わりに、サーバーで個別のチャネル アダプターを使用することを選択した特定の理由はありますか?

送信ゲートウェイにいくつかの改善が加えられた 2.2.3 への移行を検討することをお勧めします (ただし、サーバーによる適切な関連付けが必要です)。

編集:以下のコメントごとに...

代わりにアダプターのペアを使用したい場合、現在の構成では、 を使用し<header-enricher/>て受信ヘッダーjms_messageidをにコピーする必要がありますjms_correlationId

または、クライアント側 (送信ゲートウェイ) で、correlation-key属性をに設定しますJmsCorrelationId。これにより、ゲートウェイが送信メッセージにそのヘッダーを設定するようになり、サーバー側では何も必要ありません。

于 2013-04-11T12:33:53.677 に答える