使用客户机连接连接到多个 IBM MQ 队列管理器

可以将客户机连接的应用程序配置为连接到多个队列管理器 (出于负载均衡或服务可用性原因)。

IBM® MQ 客户机中实现此目的的主要机制是使用客户机通道定义表,请参阅 配置客户机通道定义表或连接列表。

也可以通过使用外部负载平衡产品或将IBM MQ连接代码封装在 "存根 "中来实现类似的行为,"存根 "可以重定向主机名或 IP 地址。

其中每种方法都有一些限制,可能或多或少适用于特定应用程序需求。 以下部分虽然并非详尽无遗,但描述了您应该考虑的特定方面,以及这些不同方法对这些方面的影响。

IBM MQ uniform clusters (see 关于均匀集群) provide a powerful mechanism to achieve horizontal scaling of applications across multiple queue managers, building on the basic mechanism of the CCDT to provide multiple destinations. 统一群集提供的功能超出了使用外部负载平衡器所能提供的功能,因为外部负载平衡器并不知晓底层IBM MQ协议,而且还能避免本主题稍后讨论的一些问题,因此在适用情况下,应考虑优先使用统一群集,而不是其他技术。

注意:某些应用环境需要特别注意IBM MQ连接的负载平衡。 在以下情况下,负载平衡可能会导致不确定或不可靠的行为。 如果您在这些情况下使用负载平衡,并联系IBM支持部门寻求帮助,可能会要求您在没有连接重定向的情况下重新创建任何问题。
  • 与队列管理器建立多个连接的应用程序。 此类应用程序包括任何使用 IBM MQ 类的 JMS 或使用 IBM MQ 类的 Jakarta Messaging,因为这些类在一般使用中会创建多个 IBM MQ 连接。 如果使用外部负载平衡器或自定义代码存根,则必须始终将同一应用程序实例的连接路由到同一队列管理器。
  • 使用 XA 事务管理或Java事务 API (JTA) 的应用程序。 此类应用程序必须始终连接或重新连接到同一个队列管理器。 如果您使用的负载平衡技术无法确保这种一致性,您就无法可靠地使用 XA 或 JTA。
  • 统一集群应用平衡。 这一功能依赖于能够指示客户端不受干扰地重新连接到特定队列管理器。 因此,不宜尝试将外部负载平衡与使用统一群集结合起来

在可能的情况下,考虑使用 "IBM MQ统一集群,而不是外部负载平衡技术。

本资料中使用的术语

CCDT 多队列管理器
这是一个 CCDT 文件,其中包含多个具有相同组(即队列管理器名称客户机连接 (QMNAME CLNTCONN) 属性)的客户机连接 (CLNTCONN) 通道,其中不同的 CLNTCONN 条目会解析为不同的队列管理器。
这与包含多个 CLNTCONN 条目的 CCDT 文件不同,后者中的 CLNTCONN 条目只是同一多实例队列管理器(可以选择将此方法与代码存根结合使用)的不同 IP 地址或主机名。
如果您确实选择了 CCDT 多队列管理器方法,那么需要选择是划分条目优先级还是使用随机工作负载管理 (WLM):
划分优先级
使用多个按字母顺序排序的条目以及 CLNTWGHT(1) 和 AFFINITY(PREFERRED) 属性来记住最后一个正常连接。
随机
使用 CLNTWGHT(1) 和 AFFINITY(NONE) 属性。 您可以通过调整 CLNTWGHT 来调整不同比例的 IBM MQ 服务器之间的 WLM 权重
注: 您应该避免 CLNTWGHT 在通道之间存在较大差异。
负载均衡器
表示使用多个 IBM MQ 队列管理器的 TCP/IP 侦听器的端口监视配置了虚拟 IP 地址 (VIP) 的网络设备。 在网络设备中配置 VIP 的方式取决于您所使用的网络设备。

以下选项仅与发送消息或启动同步请求和回复消息传递的应用程序相关。 在“将消息侦听器连接到队列”中详细讨论了可处理这些消息和请求的应用程序的注意事项(例如,侦听器完全分离)。

连接到单个队列管理器的现有应用程序所需的代码更改规模

CONNAME 列表、CCDT 多队列管理器和负载均衡器
MQCONN("QMNAME") 到 MQCONN("*QMNAME")
队列管理器名称可能在 Java Platform, Enterprise Edition (Java EE) 应用程序的 Java 命名和目录接口 (JNDI) 配置中。 否则,这需要进行一次单字符代码更改。
代码存根
用代码存根替换现有的 JMS 或 MQI 连接逻辑。

支持不同的 WLM 策略

CONNAME 列表
仅限“划分优先级”。
这可能会对代码产生负面影响。
CCDT 多队列管理器
“划分优先级”或“随机”。
这不太可能对代码有任何影响。
负载均衡器
任何(包括适用于所有消息的每一个连接)。
这可能会对代码产生正面影响。
代码存根
任何(包括适用于所有消息的每一条消息)。
这可能会对代码产生正面影响。

主队列管理器不可用时的性能开销

CONNAME 列表
始终先在列表中尝试。
这可能会对代码产生负面影响。
CCDT 多队列管理器
记住最后一个正常连接。
这可能会对代码产生正面影响。
负载均衡器
端口监视可防止使用错误的队列管理器。
这可能会对代码产生正面影响。
代码存根
可记住最后一个正常连接,然后智能地进行重试。
这可能会对代码产生正面影响。

XA 事务支持

CONNAME 列表、CCDT 多队列管理器和负载均衡器
事务管理器需要存储用于重新连接到相同队列管理器资源的恢复信息。
解析为不同队列管理器的 MQCONN 调用通常会使此信息无效。 例如,在 Java EE 中,使用 XA 时,单个连接工厂应解析为单个队列管理器。
这可能会对代码产生负面影响。
代码存根
代码存根可满足事务管理器的 XA 需求(例如,多个连接工厂)。
这可能会对代码产生正面影响。

管理员可以灵活地隐藏应用程序的基础结构更改

CONNAME 列表
仅限 DNS。
这可能会对代码产生负面影响。
CCDT 多队列管理器
DNS 和共享文件系统、共享文件系统或 CCDT 文件推送。
这不太可能对代码有任何影响。
负载均衡器
动态虚拟 IP 地址 (VIP)。
这可能会对代码产生正面影响。
代码存根
DNS 或单个队列管理器 CCDT 条目。
这不太可能对代码有任何影响。

避免计划维护期间出现中断

您还需要考虑并规划另一种情况,即如何在队列管理器的计划维护期间避免应用程序中断,例如,向最终用户显示的错误和超时。 避免中断的最佳方法是在停止队列管理器前移除其中的所有工作。

考虑一个请求/应答场景。 您希望所有未完成的请求都会完成,并且由应用程序处理应答,但是不希望将任何其他工作提交到系统。 仅停顿队列管理器并不能满足此需求,因为正确编码的应用程序在收到未完成请求的回复消息之前,会收到返回码 RC2161 MQRC_Q_MGR_QUIESCING 异常。

您可以在用于提交工作的请求队列上设置 PUT(DISABLED),并在回复队列上保留 PUT(ENABLED) 和 GET(ENABLED)。 通过这种方式,您可以监视请求、传输和回复队列的深度。 在全部稳定(也就是,未完成的请求都已完成或超时)后,便可以停止队列管理器。

但是,必须在请求应用程序中进行正确编码才能处理 PUT(DISABLED) 请求队列,这将在尝试发送消息时产生返回码 RC2051 MQRC_PUT_INHIBITED 错误。

请注意,创建与 IBM MQ的连接或打开请求队列时不会发生异常。 仅当尝试实际使用 MQPUT 调用来发送消息时才会出现此异常。

通过构建包含这种用于请求和应答场景的错误处理逻辑的代码存根,并让应用程序团队在以后使用此类代码存根,可以帮助开发具备一致行为的应用程序。