IBM WebSphere MQ 请求/回复场景

Posted

技术标签:

【中文标题】IBM WebSphere MQ 请求/回复场景【英文标题】:IBM WebSphere MQ request/reply scenario 【发布时间】:2014-06-14 01:26:39 【问题描述】:

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

但是,我无法完全理解这实际上是如何工作的。

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

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

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

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

【问题讨论】:

为了添加到其他响应中,WMQ 保留了 MsgIDCorrelID 字段的索引,因此这些字段上的任何 GET 不需要遍历所有消息以找到正确的一。请参阅 WMQ 信息中心中的Designing WebSphere MQ applications,了解有关开发排队应用程序的更多讨论。 【参考方案1】:

通常使用 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 实现提供了基于优先级的消息传递,即优先级高的消息首先传递,或者基于 FIFO 的消息传递,队列顶部的消息首先传递。也可以使用上面示例中说明的选择标准来检索消息。

希望这有帮助

【讨论】:

感谢您对它的工作原理进行全面而详细的解释! 从 1) 到 4) ;大概持续时间是多少毫秒? @Shashi,如果服务应用程序知道将响应消息放入哪个队列,是否必须设置ReplyQ? IIB中发送请求和接收响应流可以分开吗? 不,不需要,只要服务知道将响应放在哪里并且请求者知道从哪里读取回复,就不需要设置ReplyQ。我对 IIB 的了解非常有限,我认为这些流程可以分开,因为这完全是关于将请求发送到哪里以及响应流到哪里。【参考方案2】:

Shashi 的回答适用于许多情况,实际上是在多个请求量相对较低的应用程序之间分配响应的主要方法。

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

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

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

我希望这也有帮助。

【讨论】:

谢谢你,真的很高兴知道! 我必须补充一点,实际上并不能保证响应按您期望的那样排序——服务应用程序可能并行处理多个消息(或者可能有多个服务应用程序),并且处理请求之间的持续时间可能不同。您必须积极设计您的应用程序以维持秩序。

以上是关于IBM WebSphere MQ 请求/回复场景的主要内容,如果未能解决你的问题,请参考以下文章

IBM websphere MQ 消息发送与获取

IBM WebSphere MQ安装集成

IBM WebSphere MQ安装集成

IBM Websphere MQ 基本实验操作

连接到 IBM Websphere MQ 时出现 NullPointerException

第十一章 发送和接收IBM WebSphere MQ消息