与JMS / ActiveMQ并发同步请求 - 模式 - 模式/库?

时间:2012-08-01 08:11:07

标签: java multithreading jms activemq

我有一个网络应用程序,当用户提交请求时,我们将JMS消息发送到远程服务,然后等待回复。 (还有异步请求,我们为消息重放设置了各种各样的细节,所以我们更喜欢坚持使用JMS而不是HTTP)

How should I implement request response with JMS?中,ActiveMQ似乎不鼓励每个请求的临时队列或JMSCorrelationID上具有选择器的临时使用者的想法,因为旋转它们会产生开销。

但是,如果我使用池化的消费者进行回复,我如何从回复消费者发送回原始请求线程?

我当然可以编写自己的线程安全回调 - 注册/发送,但我讨厌编写我怀疑已经由比我更了解的人编写的代码。

ActiveMQ页面推荐自{2006年以来尚未更新的LingoCamel Spring Remoting,我的团队因其许多陷阱错误而被我们团结起来。

是否有一个更好的解决方案,以实现此模式的库的形式,或者以不同模式的形式来模拟JMS上的同步请求 - 回复?


相关问题:

5 个答案:

答案 0 :(得分:4)

在过去的项目中,我们遇到了类似的情况,其中使用一对Async req / res JMS消息处理了同步WS请求。我们当时正在使用Jboss JMS impl而临时destinations这是一个很大的开销。

我们最终编写了一个线程安全的调度程序,让WS等待JMS响应进入。我们使用CorrelationID将响应映射回请求。

这个解决方案已全部成熟,但我遇到了一个很好的阻塞映射impl,解决了匹配请求响应的问题。

BlockingMap

如果您的解决方案是群集的,则需要注意将响应消息分派到群集中的正确节点。我不知道ActiveMQ,但是我记得JBoss的消息传递在他们的可聚集目的地下面有一些故障。

答案 1 :(得分:4)

我仍然会考虑使用Camel并让它处理线程,可能没有spring-remoting但只是原始的ProducerTemplates。

Camel有一些关于该主题的很好的文档,并且与ActiveMQ非常兼容。 http://camel.apache.org/jms#JMS-RequestreplyoverJMS

对于关于启动基于选择器的消费者和开销的问题,ActiveMQ文档实际指出的是它需要往返于全球另一端或高延迟网络的ActiveMQ代理的往返。这种情况下的开销是到AMQ代理的TCP / IP往返时间。我认为这是一个选择。已成功使用它多次。

答案 2 :(得分:3)

一位同事建议了一个潜在的解决方案 - 每个webapp线程一个响应队列/消费者,我们可以将返回地址设置为该特定线程拥有的响应队列。由于这些线程通常是长期存在的(并且被重用于后续Web请求),因此我们只需要在池生成线程时承受开销。

那就是说,整个练习让我重新思考JMS与HTTP ......:)

答案 3 :(得分:0)

我一直使用CorrelationID来处理请求/响应,并且从未遇到任何性能问题。我无法想象为什么这将是一个性能问题,它应该是任何消息传递系统实现的超快速,并且实现良好的非常重要的特性。

http://www.eaipatterns.com/RequestReplyJmsExample.html有使用replyToQueue或correlationID的两个主流解决方案。

答案 4 :(得分:0)

这是一个旧的,但我已经来到这里寻找其他东西并且确实有一些见解(希望对某人有帮助)。

我们实施了非常类似的用例,Hazelcast是我们的底盘 集群的节间通信。本质是2个数据集:1个响应的分布式地图,1个本地'响应等待者列表(在群集中的每个节点上)。

  • 每个请求(从Jetty接收它自己的线程)在本地等待者的地图中创建一个条目;该条目显然具有相关性UID和将用作信号量的对象
  • 然后将请求分派到远程(REST / JMS),原始线程开始等待信号量; UID必须是请求的一部分
  • remote返回响应并将其写入具有相关UID的响应映射
  • 正在听取回应地图;如果在本地等待者的地图中找到新来的响应的UID,则通知其信号量,正在发布原始请求的线程,从响应图中获取响应并将其返回致客户

这是一般性描述,如果有任何兴趣,我可以通过一些优化来更新答案。