有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用JMS/ActiveMQ模式/库的java并发同步RequestReply?

我有一个web应用程序,当用户提交请求时,我们向远程服务发送JMS消息,然后等待回复。(还有异步请求,我们为消息重播等设置了各种细节,因此我们更愿意使用JMS,而不是HTTP)

How should I implement request response with JMS?中,ActiveMQ似乎不鼓励对每个请求使用临时队列,或者在JMSCOrrationId上使用选择器的临时使用者,因为这会增加开销

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

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

ActiveMQ页面推荐了Lingo,自2006年以来一直没有更新过,以及Camel Spring Remoting,我的团队因为它的许多gotcha bug而禁止了它

是否有更好的解决方案,以实现此模式的库的形式,还是以模拟JMS上同步请求-应答的不同模式的形式


有关问题:


共 (5) 个答案

  1. # 1 楼答案

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

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

    这个解决方案都是国产的,但我遇到了一个很好的阻塞映射impl,它解决了将响应与请求匹配的问题

    BlockingMap

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

  2. # 2 楼答案

    我一直使用CorrelationID进行请求/响应,从未遇到任何性能问题。我无法想象为什么这会成为一个性能问题,对于任何消息传递系统来说,它的实现都应该是非常快的,并且是一个非常重要的特性

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

  3. # 3 楼答案

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

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

  4. # 4 楼答案

    这是一个旧的,但我已经登陆这里寻找其他东西,实际上有一些见解(希望将有助于某人)

    我们已经实现了非常类似的用例,Hazelcast是我们的底盘 簇的节间融合。essense是2个数据集:1个响应的分布式映射,1个响应等待器的“本地”列表(在集群中的每个节点上)

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

    这是一个一般性的描述,我可以通过一些优化来更新答案,以防有人感兴趣

  5. # 5 楼答案

    我仍然会考虑使用Camel,让它处理线程,也许不需要spring远程处理,只需要原始产品模板

    Camel有一些关于这个主题的文档,可以很好地与ActiveMQ配合使用。 http://camel.apache.org/jms#JMS-RequestreplyoverJMS

    对于您关于旋转基于选择器的使用者和开销的问题,ActiveMQ文档实际说明的是,它需要往返到ActiveMQ代理,后者可能位于地球的另一端或在高延迟网络上。这种情况下的开销是到AMQ代理的TCP/IP往返时间。我认为这是一种选择。多次成功地使用它