【问题标题】:JMS from Synchronous to AsynchronousJMS 从同步到异步
【发布时间】:2016-10-16 08:00:54
【问题描述】:

我能够使用 JMS 创建同步服务总线,但无法将其转换为异步。 我正在尝试异步向服务发布请求,因此如果服务关闭,我希望 JMS 队列保留请求消息,并且在服务启动时将消息传递给服务并取回响应。

这是我的代码

<camelContext xmlns="http://camel.apache.org/schema/spring">
        <route >
            <from id ="server" uri="jetty:http://0.0.0.0:9500/rsb/toService?matchOnUriPrefix=true&amp;enableMultipartFilter=false&amp;disableStreamCache=false"/>
            <wireTap uri="log:test?level=INFO"><body><simple>Enter JMS test route and sending message to queue</simple></body></wireTap>
            <!--<to uri="direct:queue"/>-->
            <to uri="jms://testqueue?requestTimeout=360000&amp;replyTo=bar&amp;replyToDeliveryPersistent=true&amp;exchangePattern=InOut&amp;acknowledgementModeName=AUTO_ACKNOWLEDGE"/>
        </route>
        <route id="testqueuelistener" streamCache="true">
            <from uri="jms://testqueue?replyToDeliveryPersistent=true&amp;replyTo=bar" />
            <wireTap uri="log:test?level=INFO"><body><simple>Message recieved from queue: ${body}</simple></body></wireTap>             
            <to uri="http://localhost:18402/Home/addUser?bridgeEndpoint=true&amp;throwExceptionOnFailure=false"/>
            <to uri="jms:service"/> 
        </route>
        <route >
            <from uri="jms:service"/>
            <transform>
                <simple>${body}</simple>
            </transform>
        </route>
    </camelContext>

【问题讨论】:

  • 你遇到的实际问题是什么(当你尝试这个时会发生什么)?另外,您使用哪种 JMS 实现,它是如何配置的?
  • jms 配置 我的实际问题是如果服务 "localhost:18402/Home/addUser";已关闭 - 未运行 - 我收到错误 404 Not Found 访问 /rsb/toService 时出现问题。原因:未找到我希望将请求消息保留在队列“testqueue”中,直到服务启动然后接收队列中的消息。

标签: spring asynchronous apache-camel jms


【解决方案1】:

问题是您在没有使用事务的情况下访问 JMS 队列 - 因此,一旦您收到消息,它就会从队列中消失。您需要使用事务并且仅在完成处理后提交(或回滚)消息消费。

相关的企业集成模式是transactional client。 JMS component documentation 还提供了一些关于事务的信息。最后,Camel in Action 的第 9 章(第二版的第 12 章)专门讨论交易(我怎么推荐都不为过!)。

你需要:

  • 获取 JMS 事务管理器(您使用的事务管理器可能取决于您的具体用例)
  • 配置 Camel JMS 组件以使用事务管理器
  • 使用事务策略来配置路由的事务行为(或者只是将路由标记为已事务,并使用默认策略)

配置可能类似于:

<!-- Import JMS connection factory -->
<osgi:reference id="jmsConnectionPool" interface="javax.jms.ConnectionFactory" />
<!-- We create a Spring JmsTransactionManager (our transaction manager could also be an
imported OSGi service, like we do for the connection factory; for example an XA transaction
manager) -->
<bean id="jmsTxManager" class="org.springframework.jms.connection.JmsTransactionManager">
    <property name="connectionFactory" ref="jmsConnectionPool"/>
</bean>
<!-- We configure the JMS component to use the transaction manager-->
<bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
    <property name="connectionFactory" ref="jmsConnectionPool" />
    <property name="transacted" value="true"/>
    <property name="transactionManager" ref="jmsTxManager"/>
</bean>

<!-- Here's an example of a transaction policy -->
<bean id="requiresNew" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
    <property name="transactionManager" ref="jtaTransactionManager"/>
    <property name="propagationBehaviorName" value="PROPAGATION_REQUIRES_NEW"/>
</bean>

这是一个交易路线:

<route id="myRoute">
    <from uri="jms://..." />
    <transacted/>
    ...
</route>

如果我们愿意,路由可以使用特定的事务策略:

<route id="myRoute">
    <from uri="jms://..." />
    <transacted ref="requiresNew" />
    ...
</route>

【讨论】:

  • 我可以在收到回复时添加相同的选项吗?
猜你喜欢
  • 2015-08-01
  • 1970-01-01
  • 2019-06-14
  • 1970-01-01
  • 2013-08-01
  • 2020-08-01
  • 1970-01-01
  • 2014-04-01
  • 2010-12-12
相关资源
最近更新 更多