IBM WebSphere MQ请求/回复方案

时间:2014-04-28 13:14:27

标签: jms message-queue ibm-mq

我目前正在开发一个项目,我需要与IBM系统进行交互,该系统通过WebSphere MQ与外部世界进行通信。我需要使用队列以“请求 - 响应”方式查询系统,我将通过队列管理器执行此操作。

然而,我无法理解这在实际操作中是如何运作的。

假设我有同一个应用程序的多个实例,它们将消息放入请求队列。离开应用程序时,消息将获得CorrelationIdMessageId,并在每条消息上设置ReplyToQueue属性,以确保队列管理器知道将响应放入哪个队列。< / p>

但是,队列管理器如何操作响应队列?对于响应的时间安排无法保证,那么正确的响应如何回到发出相应请求的应用程序实例呢?

我一直认为消息队列是一个FIFO队列,必须逐个拾取消息。但是,这意味着实例A可以选择一个针对例如B的响应。显然,这不是它的工作原理。

然后,当我查看API(com.ibm.mq.MQQueue)时,我看到要选择一条消息,我有机会提供请求消息的CorrelationIdMessageId。这是否意味着当我向队列管理器查询消息(具有这些ID的集合)时,队列管理器会遍历队列中的消息并返回匹配的消息?另一方面,这意味着我们不是在谈论FIFO队列吗?

2 个答案:

答案 0 :(得分:18)

通常的做法是使用CorrelationId来关联请求和响应消息。它的工作原理如下:

1)假设有两个队列,一个REQQ请求队列,其中放置消息,要求另一个应用程序,服务应用程序接收和处理,以及服务应用程序向其发送回复的RESPQ。

2)请求者应用程序(让它将其称为REQAPP)将请求消息(REQMSG)放入请求队列(REQQ)。在发送消息之前,REQAPP将消息的ReplyToQ属性设置为RESPQ。发送请求消息时,JMS提供程序使用唯一的MessageId更新已发送的消息。请求者应用程序缓存此唯一的MessageId供以后使用。

3)在世界的另一端,服务应用程序从REQQ检索REQMSG,从该消息中读取MessageId和ReplyToQ属性,处理请求并准备适当的响应消息RESPMSG。然后,它将RESPMSG的CorrelationId属性设置为从REQMSG读取的MessageId,并将回复放回ReplyToQ。

4)请求者应用程序在阅读回复时,使用缓存MessageId并设置如下选择标准来阅读回复消息

GET MESSAGE FROM RESPQ WHERE RESPMSG.CORRELATIONID==REQMSG.MESSAGEID

此选择标准可确保检索到正确的响应消息。这里的关键是服务应用程序必须将响应消息上的CorrelationId设置为请求消息的MessageId。

虽然Queue是FIFO类型,但MQ实现在优先级基础上提供消息传递,其中首先传递具有高优先级的消息或者首先传递队列顶部的消息。也可以使用选择标准检索消息,如上例所述。

希望这有帮助

答案 1 :(得分:5)

Shashi的答案在许多情况下都很有用,实际上是在多个相对低容量的请求应用程序之间分配响应的主要方法。

大批量服务的更好选择将涉及多个RESPQ。您可以通过使用临时动态队列来接收RESPMsgs为REQApp的每个实例提供单独的RESPQ - REQApp的每个实例都将使用MQOPEN函数创建TDQ,并在它发出的每条消息的ReplyToQ属性中指定RESPQ名称。

使用此设置,您不必担心排序和相关ID,因为消息将按照服务应用程序处理它们的相同顺序返回到各个RespQ。

值得注意的是,TDQ只是暂时的。当OPENing应用程序关闭队列时 - 通过MQCLOSE或终止 - TDQ中的任何消息都将丢失且无法恢复。如果这是一个问题 - 无论如何都必须处理所有响应 - 那么您希望一次性分配一系列永久动态队列(也使用MQOPEN),每个REQApp实例一个,REQApp的每个实例都必须每次都重新连接到同一个队列。

我希望这也有帮助。