消息中间件 MQ 企业级方案设计

1 篇文章 1 订阅

第 1 部分: 异步通信与负载均衡

 

引言

  Websphere MQ 是 IBM 功能强大的消息传送中间件产品,它以其成熟的技术和世界领先的产品向我们提供了的功能丰富、可靠易用的异构平台间实现可靠信息传递的成熟解决方案。使用 MQ 消息传递产品可以帮助业务应用在不同种类平台上交换信息,以消息的方式接收、发送数据,从而实现企业应用集成。MQ 屏蔽了异构软硬件平台和网络协议的复杂性,确保“消息到达并且仅到达一次”的可靠的消息传递,满足高可靠性的、高性能的、安全可靠的稳定信息数据传输要求,并具有开放性、扩展性、先进性、安全性、可管理性和易于维护开发等特性。依靠这些优势,MQ 在消息类中间件市场上占有统治地位,已经成为事实上的行业标准,在企业的各类应用中承担了可靠的信息数据传输的基础支撑。MQ 是为能够支撑大型企业的海量信息传输而设计的,它设计了很多应用特性,为企业级应用提供支持,这些特性分散在系统设计和应用编程的各种细节之处。本系列以使用 IBM 大型机服务器的客户为主要对象,对异步通信与同步通信、MQ 高可用性及负载均衡方案、MQ 的安全性实现、MQ 与传统 CICS 应用的连接、使用 MQ 实现 SOA 服务、MQ 应用性能监控和企业级应用设计构架等几个方面探讨如何应用 MQ 的特性实现企业级应用的业务需求。本文是本系列的第 1 部分,将为大家介绍异步通信与同步通信的特点与设计考虑以及 MQ 高可用性及负载均衡方案。

  异步通信与同步通信

  异步通信与同步通信的特点

  MQ 在支持同步通讯的同时,提供了基于消息队列存储 - 转发机制的异步通讯模式,应用程序只需将消息交给 MQ,就由 MQ 负责将消息安全、可靠地发送出去,不再需要应用和人工的干预,真正实现了数据传输自动化,这一特点能够使应用程序独立于通信对方和网络的可用性。与我们常见的同步通信相比,异步通信模式有以下特点:

  通信的达成只依赖于发送方和消息中间件,接收方以及网络的意外情况不造成影响。

  因为不必实现同步握手,异步通信通常效率更高。

  因为不必等待响应,异步通信倾向于实现更短的交易处理,节省系统资源占用。

  异步通信有利于提高系统并发度,提高系统吞吐能力。

  异步通信有利于实现松散耦合的系统结构。

  与异步通信相比,同步通信想法更为简单而且更容易实现――发起方在系统中等待直到对方响应,这样可以避免复杂的发送 / 确认 / 重传机制的设计,但同时也造成了低效率和对资源占用大的缺点,同步通信目前是一种常见的廉价通信实现方式。

  需要说明的是这里谈论的同步 / 异步是底层消息传输的模式,与其最终提供的服务模式无关:同步业务服务可以通过同步通信实现,也可以通过异步通信实现。比如我们常见的电话业务,一般我们都认为是一种同步的服务,但电信公司实际实施时,如果是通过交换机,在通话双方之间建立一个电路连接,那就是一种同步通信实现;如果电信公司采用的是 IP 电话,通过网络把声音打成若干数据包在 Internet 上发送,在收话方没有感觉到的时间内再按顺序组合把语音还原出来,那就是使用的异步底层通信实现。我们进行应用方案设计时要充分意识到两种通信模式的特点,考虑各种选择的可能性和优劣。

  异步通信实现同步应用设计

  由于同步 / 异步通信有各自的特点,所以通过异步通信来实现同步应用时,有一些特殊的方法需要考虑。异步通信基础上实现同步应用,是通过若干异步消息分段实现的,以最简单的双方模式为例,A 发送给 B 一个异步消息,B 接收后完成特定处理,再返回给 B 一个异步消息,如果这个处理过程足够快,就能够实现一个请求 / 应答模式的同步应用。这种模式下,应用中 UOW 的范围,和同步应用下是有很大不同的,应用设计中要充分考虑到这种区别。

  在同步模式下,在 A 和 B 的所有操作都可以放在一个 UOW 中,通过两阶段提交协议实现数据一致;在异步模式,应用会分成几个 UOW,第一个是应用程序在本地队列管理器中的操作,第二个是两个队列管理器间的数据传输,这个 UOW 是系统完成的,对于应用是透明的,第三个 UOW 是远程应用在远程队列管理器中的操作。应用设计时要充分意识到这些区别。

由于交易一致性控制,一个 MQ 应用中在队列中进行的改变,只在它 COMMIT 后,其他应用程序才能看到,所以在进行请求 / 应答模式的 MQ 应用程序中,请求程序发送请求消息后,要在适当的位置下 COMMIT,完成这个 UOW,然后在到应答队列里去等待对方完成 UOW 后的返回。应答程序也要与请求程序类似,也要合理地控制 UOW 的范围,使得返回消息能够恰当地被请求程序得到。

  在使用 MQ 进行要求同步通讯的程序设计时,会碰到原来可能会做单一 UOW 的应用,在 MQ 下的异步应用设计下要划分成若干个 UOW,这就涉及到如何在多 UOW 下保证数据整体的一致性。这种需求,一般可以通过合理的冲正设计来实现。

  MQ Server 与 Client

  MQ 产品分为 Server 和 Client 两种版本,在 MQ Server 的运行环境下,有队列管理器、队列、消息通道等对象,它提供全面的消息服务;MQ Client 本身没有队列管理器、队列等对象,它通过 MQI 通道与服务器之间建立通讯,并将消息从客户端发往服务器端的队列,或从 Server 端的队列中取得消息,其他功能也比 Server 有限。MQ Client 与 Server 之间的通信是同步模式完成的,它必须在 Server 正在工作并且可以通过网络访问的情况下才能完成任务。MQ Client 通常在有大量末端环境的应用系统中采用,可以通过这种方式来节省成本,但要求在 Client 到 Server 之间要有比较可靠的网络连接。

  MQ 高可用性及负载均衡方案

  大型企业应用方案,在功能性要求之外系统高可靠性能力与负载均衡能力是一个十分重要的衡量指标。MQ 在这方案提供了很强的特性,主要通过两种主要技术实现:MQ Cluster 技术和 Queue Sharing Group 技术。Cluster 技术可以在各种系统平台上甚至跨平台实施,能够提供基本的高可用性能力,Queue Sharing Group 只能在 IBM System z 主机平台上实现,能够提供最高级的高可用性能力。

  MQ Cluster 方案

  MQ Cluster 结构与特点

  使用 Queue Manager Cluster 技术,可以把安装在不同平台(如 AIXLINUX,WINDOW,z/OS)上的若干个 Queue Manager 设计为一个集群,每个 Queue Manager 都创建成集群中的一员。集群中有一个或多个 Queue Manager 可以定义成拥有整个集群的对象定义信息,称作 Repository queue manager。当用户在集群中创建一个接收通道或队列时,系统会自动在其他队列管理器中创建相应的发送通道和远程队列定义。不论整个集群中有多少 Queue Manager,每个 Queue Manager 只要建立一个接收通道,和一个指向 Repository queue manager 的发送通道就可以完成消息连通,而不必要针对每个 queue manager 分别定义通道;同时每个 Queue Manager 也不必要定义远程所有用到的远程 Queue.

  图1 MQ Cluster 集群

  通过 Cluster 技术,可以有效地减少系统的管理工作,更快地建立应用同时可以提高系统的可用性并可以在集群 MQ 管理器间实现负载均衡。

  减少系统的管理工作主要体现在 :

  不论连接多少远程队列管理器,只要建一个集群发送通道和一个集群接收通道,不必为每个管理器分别建立通道

  每个队列管理器只要建立一个 transmission queues。

  不必一一定义远程队列,可直接使用

  使用 Cluster 技术提高系统的可用性和实现负载均衡,是通过在 Cluster 内的不同 QMGR 上建立同名的 Queue(同一个 Queue 的多个实例)来实现的。每个 Queue 的实例都能作为消息的目的地,MQ 能够在依照一定的算法决定实际消息应当传给哪个 QMGR。这样当集群里某个 QMGR 失效时,消息会自动路由到其他活动的 QMGR 管理的实例上去。

  典型部署模式

  在实际应用 Cluster 技术时,一般采取如下的部署方案:

  图2 MQ Cluster 的典型部署模式

  查看原图(大图)

  在 Cluster 中首先设计一台 MQ 服务器作为整个 Cluster 的网关,作为对外的连接点,它本地并不定义任何输入(Inbound)队列(如上例中的 Q1),只定义输出(Outbound)队列(如上例中的 Q2)。另外设置若干消息处理服务器,其中定义本地的输入队列,同时有消息处理程序在运行。在外部交易进入 Cluster 时首先发送到网关机上,由网关动态地发送到 Cluster 里定义了输入队列的 MQ 服务器上去。MQ 网关可以根据设置,按照轮循或权重的方式对进入的消息进行分发,还可以通过出口程序(User Exit)实现更加复杂的分发机制。

 

 

第 2 部分: MQ 的安全性、应用的连接、实现 SOA 服务以及系统监控

MQ 的安全性实现

  在实际生产系统上,安全性是一个重要的要求。除了在网络和操作系统上提供通用的保护外,在 WebSphere MQ 上,还需要提供一些安全性控制手段。首先 MQ 提供对 MQ 资源管理的安全性控制管理,确保 MQ 资源只能被合法的人定义和改动,其次 MQ 提供对 MQ 资源访问的安全性控制,确保本地 MQ 里的信息只能被合法的人使用,再次提供对 MQ 通道的安全性控制,确保只有合法的人才能够从外面向本地 MQ 传递信息。这样,通过这三个方面的保护,MQ 实现了一个安全可靠的信息处理系统。

  MQ 资源管理权限

  MQ 资源管理权限主要包括对以下操作的权限管理:

  对 MQ 服务器发布管理命令

  在 MQ 服务器上使用 WebSphere MQ Explorer

  在 z/OS 上使用 MQ 控制面板

  在 z/OS 上使用命令工具如 CSQUTIL 等

  在 z/OS 上对 MQ 数据集的访问

  把这几条路径管理好了,就能保证 MQ 系统资源配置的安全,从而不会发生恶意或意外的改变。当 MQ 部署在 z/OS 上时,它的安全认证是通过 external security manager (ESM) 实现的,在默认情况下,这个 ESM 是 RACF(Resource Access Control Facility,IBM的主机操作系统的安全管理产品),MQ 通过 RACF 里定义的 profiles 对用户访问权限进行验证。为达到目标,管理员要根据实际情况建立适当的 RACF profiles 并且为系统用户和组进行适当的授权。

  客户可以根据需要对 MQ for z/OS 的安全管理选项进行打开和关闭。如果选项关闭,则 MQ 不会做任何安全检查动作。安全管理选项的打开和关闭可以在单个 MQ Server 的粒度上实施,也可以在 Queue Share Group 的粒度上实现,也可以采用混合模式,当在 Queue Share Group 的粒度上实现时所有 MQ Server 都用相同的 RACF profiles 进行安全检查,安全管理简单而且一致,这是一种比较常用的方式。

  有关 MQ 资源管理安全的具体实现,请参考《WebSphere MQ for z/OS Version 6.0 System Setup Guide》的第 12 章:Using RACF classes and profiles。

  MQ资源访问权限

  MQ的资源访问权限主要保护如下的 MQ 资源:

  Queue managers

  Queues

  Processes

  Namelists

  这些资源可以通过如下方式进行访问:

  通过在应用程序中使用 MQI 应用接口进行访问;

  通过 MQ 管理界面进行访问;

  通过 Programmable Command Format (PCF) 命令进行访问;

  可以通过 CSQUTIL、CSQUDLQH 等工具程序进行访问。

  进行这些访问时,MQ 会进行访问权限的检查。为实现这些控制,需要在 RACF 里建立适当的 profiles 并为系统用户和组进行授权。

  一些 MQI 的命令,如 MQOPEN 和 MQPUT1 允许使用 Alternate user authority。操作时使用指定的用户名进行操作,而不是程序自己的用户名。这时需要两个条件都满足才能成功:首先运行程序的用户有使用 Alternate user authority 的权限,其次指定的用户在操作对象上有所需的权限。

  CHANNEL安全权限

  除本地 MQ 访问以外,远程 MQ Server 可以通过远程队列的方式,通过 Channel 把消息放到一个 MQ Server 的队列中;同样写入远程队列的消息也会通过 Channel 传递给远程服务器,所以 Channel 上的安全性也是 MQ 整体安全的一个重要部分。

  作为发送方通道,Channel 的用户需要有对 Transmission Queue 的访问权限,这样才能正常把消息发送到远程队列。可以通过设置通道的 MCAUSER 参数来改变 Channel 用户名,默认情况下,它将是 Channel-Initiator 的启动作业相关联的用户名。

  作为接收通道,用户要具有对目的队列和死信队列的访问权限,通道定义语句里的 PUTAUT 参数指定哪个用户标识是用于这些检查的:可以指定使用运行 Channel 的用户名进行检验,也可以指定使用接收到消息的消息头里 UserIdentifier 字段里指定的用户名进行检验。

  通信安全性 —SSL

  在MQ的通道安全性机制之上,我们可以进一步使用安全套接字层(SSL)协议来对通信链路上的数据进行保护。安全套接字层协议提供业界标准通道安全性,具有确认通信对象、防偷听、防数据篡改的功能。通过 SSL 支持可以实现以下的安全性:

 认证:启动支持 SSL 连接的队列管理器或客户机可确定它们正在连接的队列管理器的身份,正在接收连接的队列管理器可检查正在启动连接的队列管理器或客户机的身份。

  消息加密:通过使用唯一的会话密钥,SSL 可加密通过连接进行交换的所有信息。如果信息受到未授权方拦截,这可以确保此信息无法查看。

  消息完整性:数据不会在链路中被篡改。

  使用SSL通道时,当队列管理器连接至另一个队列管理器,这两个队列管理器执行证书的标准 SSL 交换和验证检查。如果验证成功,则建立连接。要达到此目的,必须使用适当的证书设置来配置这两个队列管理器以及它们将使用的通道。当消息沿着通道从一个队列管理器发送至另一个队列管理器时,通常使用证书交换期间已建立的会话密钥来加密数据。要实现 SSL 配置,必须使用适当的证书和加密算法来配置将要使用的通道。具体配置过程,请参考《WebSphere MQ Version 6.0 Security》的“Part 3. Working with WebSphere MQ SSL support ”部分。

  MQ 与传统 CICS 应用的连接

  在使用 IBM 主机的大型企业里,一般采用 CICS 作为联机交易支持系统,经过长年 IT 的发展,CICS 系统里积累了大量的企业核心业务应用,MQ 作为应用集成的重要工具,是否能够方便灵活地与 CICS 中的程序进行连接,是个重要问题。

  在主机上,MQ 与 CICS 有很好的应用集成,可以方便地从 CICS 中使用 MQ 资源,也可以容易地从 MQ 中调起 CICS 程序进行业务处理。MQ 提供两种主要的方式与 CICS 连接方式,一种称作 CICS adapter,通过 CICS adapter 的功能,CICS 应用程序可以访问 MQ 队列里的数据;另一种称作 CICS bridge,通过 CICS bridge 的功能,向某个 MQ 队列发送包含 COMMAREA 的消息,从而自动触发起 CICS 中处理程序运行,并自动把 CICS 程序返回的 COMMAREA 写到返回队列里去,这个 CICS 程序不必为 MQ 调用做任何改变。

  CICS adapter

  CICS adapter 把 CICS 与某个 MQ 队列管理器相连,使得 CICS 程序可以通过标准的 MQI应用接口访问 MQ 资源,CICS adapter 本身包括:

  一组控制功能,用来管理 MQ 与 CICS 的连接。

  MQI stub,一组函数库,通过他们,CICS 程序可以调用 MQ 资源。

  图 1 CICS adapter 程序框架

  查看原图(大图)

  上面图 1 中的例子给出了一个使用 CICS adapter 程序的例子。它可以通过MQGET()、MQPUT() 等 MQI 调用接口来访问 MQ 资源。MQ 还会在 CICS 中安装一些交易程序,CKQC 交易用来管理 CICS/MQ 的连接和对 CICS adapter 自身进行管理。CKTI 交易是任务初始化程序,它用来监控 MQ 触发信息,如果某个 MQ 队列上定义的触发程序是 CICS 程序,触发条件符合时将由 CKTI 初始化运行 CICS 程序。

  实际中,CICS adapter 的主要用法一般有两种,一种是由 CICS 程序主动发起,它读取队列信息进行处理,或者向某个队列发送响应/通知信息,比如 CICS 中的取款程序可以把帐户取款事件写入 MQ 队列,通过 MQ 传递到其它系统进行处理;另一种是 MQ 应用主动发起,向某个输入队列放入消息,这个队列上定义了触发器,指定将被触发的是某个 CICS 程序,当 MQ 的触发监控程序 CKTI 发现有消息到达,它会自动启动相应的 CICS 程序,这个 CICS 程序自己到队列里读取数据进行处理,最后把返回数据写到返回队列里去。

  CICS bridge

  WebSphere MQ-CICS bridge 提供了一种方便的手段,使 MQ 应用可以调用 CICS 程序并传递参数,这个 CICS 程序可以是现有的使用 COMMAREA 传递参数的任何程序,它里面不必做任何 MQ 调用。使用 MQ-CICS bridge 可以很容易地把现有的 CICS 传统 DPL 应用程序提供给 MQ 应用程序调用,不必对现有程序做任何改写和重新编译。对于传统的面向 3270 终端的 CICS 程序,也可以通过 3270 bridge 格式进行调用,而不必对应用进行修改。

  图 2 CICS bridge 结构

  如上图 2 所示,使用 MQ-CICS bridge 时要定义一个输入队列和一个输出队列,并对 MQ-CICS bridge 进行配置。MQ 应用程序向输入队列中放入一个包含需要传递给被调用的 CICS 程序的 COMMAREA 数据的消息,MQ 提供的 Bridge Monitor 程序会监控到有新消息到达,它会 START 一个 MQ 提供的 Bridge Task 处理程序,这个程序从队列中读取消息,取得应用所需的 COMMAREA,然后使用 LINK 命令去调用指定的 CICS 业务程序,这个业务程序处理完毕后,在 COMMAREA 里返回结果数据,Bridge Task 处理程序会把含有返回 COMMAREA 的消息写入返回队列,最后 MQ 应用从返回队列中取走数据进行显示或进一步处理。在这个过程中,对 MQ 应用来看,它把包含输入 COMMAREA 的数据写到一个队列,就可以到另一个队列去读取包含返回 COMMAREA 的结果数据;对 CICS 业务应用程序而言,它是从 COMMAREA 接收数据,从 COMMAREA 返回数据,与平常的运行一样,到底是被其他业务应用程序调用的还是被 MQ-CICS bridge 调用的,对它没有分别。

第 3 部分: 企业级应用设计构架

细看 MQ 消息头(MQMD)的功能

  MQMD 是每个消息都带有的消息头信息,它由若干字段组成,这些字段都是 MQ 设计人员根据总结的应用需求而设置的。应用程序构建消息时应该对这些字段填入恰当的值,对于没有填入的字段,MQ会用默认值填充。开发应用程序时,充分理解并利用这些字段是十分必要的,这里逐一为大家进行介绍,并针对每个字段指明它在实际编程中一般会用来实现什么样的功能:

  StrucId:消息头结构名,固定为"MQMD"四个字符。根据这个字段,我们就能够在应用程序数据包中识别出MQMD的位置。

  Version :MQMD 版本号。

  Report:消息的报告选项,默认值为 MQRO_NONE。发送方程序通过设置此字段值以指定在消息传递出现意外、消息超时、消息到达、消息递出事件时是否需要报告消息和报告消息要包含什么内容。对于需要消息报告的程序,需要对这个字段与下面介绍的 ReplyToQ 和 ReplyToQMgr 字段一起进行设置,以对这些消息事件作出反应。

  Expiry:超时字段,单位是 0.1 秒,默认值是 MQEI_UNLIMITED,表示永不过期。消息放到目标队列里以后,如果超过这个指定时间还没有被程序读走,MQ 系统就会丢弃这个消息。如果这个消息设置了 Report 字段要求超时报告,系统会按照Report字段指定的方式返回一个超时报告。应用中通常要进行必要的消息超时机制设计,比如实现SOA框架下为保持交易一致性而广泛使用的 Compensation 机制,就可以用超时处理实现。

  Feedback:反馈字段,此字段与 Report 字段一起使用以指示报告的性质。

  Encoding:消息中数值数据(binary integer、packed-decimal integers、floating-point numbers等)的编码方式,默认值是 MQENC_NATIVE,因平台而异,此值不适用于 MQMD 结构本身的数字数据。实际应用中,为减少复杂性,要尽量少使用二进制的数值数据,这时就不必考虑此字段。

  CodedCharSetId:指定消息使用的字符集编码的 CCSID,默认值是 MQCCSI_Q_MGR,随平台不同而不同。MQ 在需要转码时根据这个字段的值来识别消息内容的编码方式,在主机上一般使用包含 GBK 字符集的 CCSID1388,对应的 UNIX 和 WINDOWS 系统下的 CCSID 是 1386。

  Format:给出描述消息体所符合的数据格式名称,格式名可以自己定义,默认值是 MQFMT_NONE。应用程序可以使用这个字段来指定发送消息的格式名,接收方根据这个名字对消息体做出不同解释。

  Priority:消息的优先级,最低优先级是0,默认值是MQPRI_PRIORITY_AS_Q_DEF。

  Persistence:消息持久性值,默认值为 MQPER_PERSISTENCE_AS_Q_DEF。如果消息是持久的,所有操作会记入MQ LOG;如果消息不是持久的则不记 LOG,MQ 系统中断或重启意味着还没被处理的消息将丢失。应用程序设计时要对是否使用持久性消息进行深入的考虑,虽然持久性消息比较可靠,但它的性能比非持久消息有很大的落后,如果可以使用应用逻辑来保证数据一致性,尽量少使用持久性消息。

  MsgId :消息标识,它用来区分消息,由 MQ 自动生成,任意两个消息的 MsgId 都不同。程序执行 MQPUT 后能从 MsgId 字段得到发出消息的 ID。MsgId 在某个 QMGR 里是唯一的,但理论上两个 QMGR 可能产生相同的 MsgId,虽然这种情况实际上极少会出现。编程上要注意,不要把两个 QMGR 产生的 MsgId 进行比较。

  CorrelId:消息相关标识,应用程序可使用它来将一个消息与另一个消息相关,或将一个消息与应用程序正在执行的其它工作相关,默认值全为空。在通常的做法中,发送请求消息的程序记录下请求消息的 MsgId,服务程序读到请求消息,拿出它的 MsgId 放到回复信息的 CorrelId 字段中,发送程序在 MQGET 得到回复消息前,先把记录的 MsgId 填到消息头的 CorrelId 中,这样它就能 GET 到那条特定的回复消息。CorrelId 也可以用来设计更复杂的消息传递/识别机制。

  BackoutCount:记载消息被回滚的次数。具体介绍参见有害的消息处理。

  ReplyToQ:这是回复消息队列的名称。本字段和下面的 ReplyToQMgr 一起,构成了消息返回目的地信息。通常消息请求程序在发送请求时,就填好这些字段,消息处理程序只简单地根据要求进行回复,通过这种方式实现动态的消息回送机制。

ReplyToQMgr:这是回复消息队列所在队列管理器的名称,其默认值全为空,表示返回消息时到本地队列管理器中去找 ReplyToQ。

  UserIdentifier:它属于 MQMD 的 identity context 字段,是发起消息的应用程序的用户标识。 其默认值为空。

  AccountingToken:它属于 MQMD 的 identity context 字段,允许应用程序计算由消息引起的工作量的信息。其默认值为空。

  ApplIdentityData:它属于 MQMD 的 identity context 字段,是由应用程序定义的信息,可用来提供有关消息或其发起方的信息。其默认值为空。应用的请求和服务端可以进行协商,规定这个字段的一些专门用途,通过这个字段,来实现一定的自动化处理。

  PutApplType:它属于 MQMD 的 origin context 字段,是放入消息的应用程序类型,标志在一个消息传递串中最近的对消息进行处理的程序的信息。例如 CICS、IMS、BROKER 等。其默认值为 MQAT_NO_CONTEXT。通过本字段和下面的PutApplName字段,消息接收程序可以识别某条消息是谁发送过来的,并根据情况进行特殊的处理。

  PutApplName:它属于 MQMD 的 origin context 字段,是放入消息的应用程序的名称。其默认值为空。

  GroupId:消息组标识,MQ for z/OS 不支持消息分组。

  MsgSeqNumber:组中逻辑消息的顺序号。MQ for z/OS 不支持消息分组。

  Offset:数据的偏移量,MQ for z/OS 不支持消息分组技术。

  MsgFlags:主要是与消息分组相关的一些状态信息。

  OriginalLength:分段消息的原始长度。

  MQMD 的这些字段为我们应用程序的开发提供了很好的设施,例如当应用程序请求方需要一种方法确定哪些返回信息是针对哪条请求时,典型的做法有两种,一种是为每个请求动态创建一个临时队列,把队列名填入 ReplyToQ 字段,响应程序根据 ReplyToQ 里的值确定每条消息返回到哪个队列里去;另一种方法是响应方把原始请求的 MsgId 字段拷贝到它所发回的消息的 CorrelId 字段里去,发送方用 MsgId 搜索返回信息。

  又如 MQ 发送消息的消息头里包含了所谓的消息上下文(message context)信息,这些字段描述了消息发送者的一些情况,消息上下文又包括两部分:身份鉴别上下文(Identity context)和发送者上下文(Origin context)。身份鉴别上下文(Identity context)描述了消息最初是由谁产生的,包括 MQMD 的 UserIdentifier、AccountingToken和ApplIdentityData 字段;发送者上下文(Origin context)描述了把消息放到队列上的应用程序的情况,包括 MQMD 的 PutApplType, PutApplName, PutDate, PutTime, ApplOriginData 字段。当应用程序把一个消息进行转发时,可以选择是重新生成这些上下文还是从原消息里继承上下文。通常的做法是最初的消息发送程序由系统根据用户信息生成所有消息上下文,对消息做修改或者转发的应用,只新生成发送者上下文(Origin context),而身份鉴别上下文(identity context) 最好传递从原始消息得到的上下文信息,这样在消息处理中的任意环节,都能够了解到最初发动者的用户信息。

  根据实际业务需求,灵活地运用这些字段,可以方便地实现复杂的系统功能。

  消息类型与传输控制

  企业中通过 MQ 传输的消息有多种不同的类型,不同类型的消息有不同的处理方式。通常消息可以分为以下几类:

  数据报(datagram)消息

  一种典型的异步消息传递形式,其中应用程序发送消息但不需要响应。这种消息类型是结构最简单、效率最高的类型,应用设计时要尽量可能地使用这种模式,通过 MQ 提供的可靠的消息传输确保消息能够得到处理,对于要求较高的环境,可以设置错误报告机制。

  报告消息(report message)

  给出另一个消息相关信息的消息。报告消息能够表明消息已发送、已到达目标、已到期或由于某种原因无法处理。部分报告信息可以通过适当的设置,由系统在需要的情况下自动发送,另一些可以由应用程序根据特定的情况发送。得到报告的程序,通常需要设置发出消息的 Report、ReplyToQ、ReplyToQMgr 字段来设置希望的报告类型、返回队列名和返回队列管理器。在应用设计中,把业务需求和报告消息的功能结合起来,能够解决很多种实际需求。

同步的请求/应答消息(request/reply message)

  通过 MQ 实现同步的请求/应答机制:一个程序发送请求消息,通过 MQ 传送给消息处理方,然后到特定队列上去守听应答消息。消息处理程序从 MQ 获取输入后,进行特定的处理,然后把应答消息写入返回队列。请求程序得到应答后继续完成后续处理。这是与前两种方式相比效率较低的一种模式,它是在异步通信的基础上实现的同步应用需求。这时请求/应答程序间要通过上述的动态队列、MsgId、CorrelId 等手段完成消息的识别。这时还需要进行数据完整性的一些考虑,见下面的分析。

  应用的交易一致性控制

  MQ 事务支持特性

  和传统的交易处理系统一样,MQ 把应用程序分成若干工作单元(UOW),每个工作单元内部对数据做的更新通常是逻辑相关的,必须同时成功或回滚以保持数据完整性。为此,MQ 提供了专门的 API:MQBEGIN、MQCMIT 和 MQBACK,分别表示工作单元的开始、提交和回滚。

  MQ 不但可以提供队列数据操作上的一致性,而且通过全局事务协调器(RRS)的协调下,MQ 可以实现全局的数据一致性,例如一个程序不但处理了 MQ 消息,而且同时处理了 DB2 数据库数据、CICS 的 VSAM 文件,这些操作可以通过统一的一个确认或回滚得到一致。要注意在 CICS 中的 MQ 程序,工作单元的控制将使用 CICS的EXEC CICS SYNCPOINT 或 SYNCPOINT ROLLBACK,而不是 MQI 的命令。

  程序通过每个 MQGET 和 MQPUT 操作数据时,可以选择这次操作是放在 UOW 之内还是UOW 之外,通过对读、写时的选项参数进行设置。如果某个操作放在 UOW 之外,它的操作将不能回滚。

  对于在工作单元之内的 MQPUT 操作,由于交易隔离机制,在 COMMIT 之前,其他程序是看不到这条消息的,这点在编程中需要注意。

  有害消息的处理

  由于 MQ 消息处理有事务特性,如果队列里某条消息数据结构存在问题,程序处理它时会发生失败,这条消息会被自动回滚到队列中,下次当它再被读出时,又可能发生失败,这种情况如果没有被意识到,可能会引发严重的错误循环。为防止这种情况的发生,MQ 在消息头 MQMD 里设计了 BackoutCount 字段,如果某个消息是在同步点控制之下读取的,并且由于某种原因消息被回滚,消息描述符中的 BackoutCount 字段的值将被加1,良好的程序设计需要判断该数值,如果它大于某个阈值,则需要使用其它手段来处理该消息,比如不再对数据进行分析直接放到某个问题队列里去。在处理该消息的应用中,可以将其与设定的阈值做比较,这时,阈值会被写死在程序中,为了提高其灵活性,还可以使用队列的 BOTHRESH 和 BOQNAME 属性。这样,在例外处理中,利用 MQINQ 查询得到阈值 BOTHRESH 的大小,如果超出,可以将消息转发到 BOQNAME 指定的队列中,继而对该队列进行相应的处理。这种方法大大增强了应用程序的灵活性。

  异步通信下保持数据一致性的设计

  在使用 MQ 进行同步通讯的程序设计时,会碰到原来可能会做单一 UOW 的应用,在MQ 的异步应用设计下要划分成若干个 UOW:发送程序 PUT 到队列里是一个 UOW,接收程序 GET 又是一个 UOW,这就涉及到如何在多 UOW 下保证数据整体的一致性的问题。这种需求,一般可以通过灵活地使用 MQ 提供的消息生命周期功能和应用的冲正逻辑进行配合。在典型的情况下:

  假设请求系统向服务系统发出请求,调用服务系统上的某个数据改动交易,在请求系统做MQPUT 时,首先要设置请求消息的生命周期 T1,并且在消息到期时将消息丢弃,如果在消息发走之前消息过期,它就会在进入通道之前,被 MQ 系统丢弃;如果消息到达目的地之后,在被对方应用程序取走之前消息过期,它也将被 MQ 系统丢弃。请求系统发送请求后,到应答队列里去取结果,如果时间 T1 已过,数据尚未返回,就给用户显示"交易失败,超时"信息。

  在服务系统上,应答程序处理完请求,修改数据库后,返回结果消息,结果消息也设置生命周期T2(T2<T1),与请求消息不同的是,我们设置在消息到期时发送一个超时报告,将结果消息转发到另外一个特定的队列中,在这个队列上用触发器挂一个冲正程序,这个程序对于所有超时而没有被请求系统的程序读走的消息,发动冲正,也就是把前台没有收到返回的交易都恢复回去。

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]:MQ是指消息中间件,是一种面向消息的中间件,通过高效可靠的消息传递机制与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。它提供了消息传递和消息排队模型,在分布式环境下实现了应用解耦、弹性伸缩、冗余存储、流量削峰、异步通信、数据同步等功能。\[1\] 引用\[2\]:主从模式是MQ中的一种消息传递模式。在主从模式中,消息发送者将消息发送到一个虚拟的通道(主题或队列),而消息接收者则订阅或监听该通道。消息可能会被转发给一个或多个消息接收者,这些接收者无需对发送者做出同步回应。整个过程是异步的,发送者不关心接收者如何处理消息或是否处理完毕。\[2\] 因此,主从模式消息中间件MQ是一种通过消息传递机制实现系统间异步通信的中间件。在该模式下,消息发送者将消息发送到一个通道,而消息接收者订阅或监听该通道,接收并处理消息。这种模式可以提高系统的吞吐量,实现应用解耦,削峰填谷,以及实现日志处理和消息通讯等功能。 #### 引用[.reference_title] - *1* *2* [微服务 消息中间件MQ](https://blog.csdn.net/m0_37583655/article/details/122575034)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Java消息中间件MQ面试题重点汇总](https://blog.csdn.net/fegus/article/details/125671153)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值