如果没有可用的临时队列,那么实现请求/回复模式的最佳方法是什么?

时间:2011-01-31 10:45:42

标签: jms messaging enterprise-integration

我的客户端应用程序有很多实例。这些客户端通过消息传递将请求发送到服务器应用程序并接收回复。通常,回复将使用临时队列发送。

不幸的是,我必须使用没有临时队列或主题概念的Stomp协议。 (虽然消息经纪人有)

确保只有原始请求者收到回复的最佳方法是什么?对于这种不幸的情况,有没有最好的做法?

2 个答案:

答案 0 :(得分:4)

当多个请求者在同一队列上侦听回复时,通常的解决方案是使用相关ID来选择消息。在客户端,它看起来像这样:

  1. 在请求队列上放置一条消息并提交。
  2. 从出站消息中检索JMSMessageID(该值由代理确定,并在发送后更新消息对象)。
  3. 从回复队列接收一条消息,指出出站消息中的JMSMessageID作为选择器中的相关ID。
  4. 处理和提交。
  5. 在服务器端,它看起来像这样:

    1. 在同步点下收到消息。
    2. 处理请求并准备回复。
    3. 根据请求将响应的JMSCorrelationID设置为JMSMessageID的值。
    4. 发送消息。
    5. 提交。
    6. 消费者会将选择器设置为:activemq.selector:JMSCorrelationID=

      由于代理创建了一个应该是全局唯一的消息ID,因此使用它作为相关ID的模式可以防止在允许每个请求者指定它自己的值时发生的冲突。

答案 1 :(得分:2)

使用JMS(我发现,无论如何)实现此模式的最佳方法是为响应消息创建预配置主题,并在响应消息上使用相关选择器,以便客户端可以获得正确的之一。

更详细地说,这意味着在请求消息上设置随机ID(使用setJMSCorrelationID()),并将该消息放在请求队列上。该请求消息的使用者处理它,创建响应消息,在响应消息上设置相同的相关ID,并将其放在响应主题上。与此同时,客户端正在使用选择器表达式监听响应主题,该表达式指定了它期望的相关ID。

危险在于响应消息是在客户端可以绕过来监听之前发送的,尽管这可能不太可能。您可以尝试使用预先配置的队列来获取响应而不是主题,但我发现主题往往更可靠地工作(我选择的JMS提供商是HornetQ - 您的里程可能会有所不同)。

所有这些都告诉我,JMS非常适合请求/响应模型。 API只是不能正确支持它。这并不奇怪,因为这绝不是JMS的用例。

像计算网格(Terracotta,Gigaspaces,Infinispan等)可能会产生更好的结果,但这对你来说并不是一个真正的选择。