3

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

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

确保只有原始请求者收到回复的最佳方法是什么?对于这种不幸的情况,是否有任何最佳实践?

4

2 回答 2

4

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

  1. 在请求队列上放置一条消息并提交。
  2. 从出站消息中检索 JMSMessageID(该值由代理确定,并根据发送结果更新消息对象)。
  3. 从回复队列接收消息,指定出站消息中的 JMSMessageID 作为选择器中的相关 ID。
  4. 处理和提交。

在服务器端,它看起来像这样:

  1. 在同步点下接收消息。
  2. 处理请求并准备响应。
  3. 将响应中的 JMSCorrelationID 设置为请求中 JMSMessageID 的值。
  4. 发送消息。
  5. 犯罪。

消费者会像这样设置选择器activemq.selector:JMSCorrelationID=

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

于 2011-01-31T19:58:59.377 回答
2

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

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

危险在于响应消息在客户端可以开始收听之前发送,尽管这可能不太可能。您可以尝试为响应而不是主题使用预配置的队列,但我发现主题往往更可靠(我选择的 JMS 提供程序是 HornetQ - 您的里程可能会有所不同)。

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

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

于 2011-01-31T19:58:00.693 回答