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

Jms 如果没有可用的临时队列,实现请求/应答模式的最佳方法是什么?,jms,messaging,enterprise-integration,Jms,Messaging,Enterprise Integration,我有许多客户端应用程序的实例。这些客户端通过消息传递向服务器应用程序发送请求并接收回复。通常,将使用临时队列发送回复 不幸的是,我不得不使用Stomp协议,它没有临时队列或主题的概念。尽管消息代理已经 确保只有原始请求者才能收到回复的最佳方式是什么?对于这种不幸的情况,有什么最佳实践吗?无论如何,我发现用JMS实现这种模式的最佳方法是为响应消息创建一个预配置的主题,并在响应消息上使用相关选择器,以便客户机能够获得正确的主题 更详细地说,这意味着使用setJMSCorrelationID在请求消息

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

不幸的是,我不得不使用Stomp协议,它没有临时队列或主题的概念。尽管消息代理已经


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

无论如何,我发现用JMS实现这种模式的最佳方法是为响应消息创建一个预配置的主题,并在响应消息上使用相关选择器,以便客户机能够获得正确的主题

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

危险在于,响应消息在客户机能够开始监听之前就被发送了,尽管这可能不太可能。您可以尝试使用预先配置的响应队列而不是主题,但我发现主题往往更可靠。我选择的JMS提供商是HornetQ—您的里程可能会有所不同

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


类似计算网格Terracotta、Gigaspaces、Infinispan等可能会产生更好的结果,但这并不是您真正的选择。

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

在请求队列上放置消息并提交。 从出站消息中检索JMSMessageID。该值由代理确定,并作为发送的结果更新消息对象。 从应答队列接收消息,将出站消息中的JMSMessageID指定为选择器中的相关ID。 处理并提交。 在服务器端,它如下所示:

在同步点下接收消息。 处理请求并准备响应。 将响应上的JMSCorrelationID设置为请求中的JMSMessageID值。 发送消息。 犯罪 使用者将如下设置选择器:activemq.selector:JMSCorrelationID=


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

我想这将在很大程度上取决于您使用的技术,而您没有提到。我想要一个与JMS兼容且与任何具体消息传递实现无关的解决方案。我本可以提到我正在使用ActiveMQ,但我不想让我的应用程序依赖于只有使用ActiveMQ才能实现的东西。@DR:stomp协议几乎将您锁定在ActiveMQ中,不是吗?没有一个真正的企业JMS提供者使用它。您只需将回复JNDI对象配置为指向模型队列。应用程序不知道临时队列和预定义队列之间的区别。它只知道JNDI对象名。我不熟悉其他供应商的实现,但他们中的大多数不是都有类似的实现吗?@t.Rob:问题更多:什么是确保只有请求的客户机收到响应而不是任何其他响应的最佳方法。尽管这种竞争条件不太可能,但您的应用程序是否普遍接受?我主要在金融部门工作,所以我不习惯这些信息可以随意使用,即使这种情况很少发生。我很好奇这种模式的使用频率。@T.Rob:我从未见过这种情况发生,没有,但我可以想象这种情况会发生在高吞吐量的场景中。此外,这将取决于您的网络/VM体系结构和JMS实现。