WebSphere MQ概念与原理

参考书籍
《精通WebSphere MQ》

1.简介

1.1消息中间件

1.1.1消息中间件

在早先的时候,人们往往使用两个程序之间直接通信的方式。这种办法最大的问题就是通信协议相关性,也就是说与通信协议相关的代码充斥在应用程序之中,而且可能出现在程序的任何地方, 甚至影响程序的设计与结构。这种办法的另一个问题就是应用程序不容易写出可靠强壮的代码。应用程序的通信部分会因为工作方式的灵活性、网络协议的通用性,以及为实现一些实用功能变得非常庞大,往往超过应用程序本身的逻辑代码,变得本末倒置, 且代码很难写好,也很难维护。

人们开始慢慢意识到应该把通信代码放到外面,变成独立的工作进程或工作模块,不同的工作进程可以适同于不同的通信协议,而应用程序与通信程序之间使用通用的本地通信方式。这样一来,应用程序与通信程序的代码完全分开,各自的逻辑清晰自然,易于管理与维护,在通信方式上前进了一大步。但是,这种方式对通信程序的编程要求比较高,如果考虑到平台的广泛适用性,通信程序可能要写一大堆,要设计一个通用高效的本地通信接口也非易事,再考虑到通信上的一些附加功能,其实现对普通编程人员是有一定困难的。人们很自然地想到,这种工作最好交由专业的通信软件来完成。

于是,市场逐渐出现了专门负责消息通信的软件。它通常是一个独立运行的通信环境,有统一的编程调用接口,可以跨平台,跨协议。不同结点之间的软件可以通过配置相互连通, 搭起统一的通信平台,从而出现更强大的功能。这种通信软件往往安全可靠、配置灵活,其地位在操作系统之上,在应用程序之下,所以被称为消息中间件 (MOM)。WebSphere MQ 就是其中的一款。

1.1.2WebSphere MQ

WebSphere MQ 是 IBM 公司于 2003 年 2 月推出的面向消息传递的中间件产品,是 IBM MQSeries 产品线的最新力作。

WebSphere MQ 在面向消息传递的中间件 (Message Oriented Middleware, MOM) 市场中赫赫有名,是用来连接异构平台之间企业应用的专业产品。通过 WebSphere MQ 可以屏蔽不同的通信协议之间的差别,可以最大程度地简化网络编程的复杂性。通过 MQ 的配置, 通信双方的程序可以以松耦合的方式独自运行,并不关心对方所在的位置和状态,通过消息驱动或消息触发的方式来相互联系。它支持多种平台,对消息支持交易式的提交与回滚。

1.1.3WebSphere MQ 产品

IBM 公司将 WebSphere MQ 分成三个不同版本的产品:WebSphere MQ Express , WebSphere MQ,WebSphere MQ Extended Security Edition。其中,WebSphere MQ 是核心产品。

基本上,WebSphere MQ 包含了 WebSphere MQ Express 的全部功能,而 WebSphere MQ Extended Security Edition 又包含了 WebSphere MQ 的全部功能。

WebSphere MQ产品

1.2 概念与对象

WebSphere MQ 运行环境中有较多的概念,其中有一部分是可以作为实体进行的操作的,称为 MQ 对象。每一个对象都有各自的属性,不同的属性决定了对象的特性和工作方式。消息、队列、队列管理器、通道是 MQ 中最重要的概念和对象。

1.2.1消息(Message)

消息是 WebSphere MQ 中最小的概念,本质上就是一段数据,它能被一个或多个应用程序所理解,是应用程序之间传递的信息载体。消息可以大致分成两部分: 应用数据体和消息数据头。
消息的结构

  • 消息数据头是对消息属性的描述,这段信息往往被队列管理器用来确定对消息的处理。消息数据头可以由应用程序或系统的消息服务程序共同产生,它包含了消息在传送中的必要信息,如目标队列管理器的名字,目标队列的名字,以及消息的其它一些属性。
  • 应用数据体是应用间传送的实质的数据消息,它可以是字串、数据结构甚至二进制数据。包含的内容可以是文本、文件、声音、图像等任何数据,这些数据只对特定的应用具有特定的含义。所以,应用数据体的结构和内容由应用程序定义,通信双方需要事先约定报文格式。

消息可以分成持久 (Persistent) 消息和非持久 (Non-Persistent) 消息。所谓“持久”的意思,就是在 WebSphere MQ 队列管理器重启动后,消息是否仍然能保持。

在 WebSphere MQ 中,消息可以是有限长度的任何一段信息。所谓有限长度,在开放平台 (Windows NT/2000/XP,AIX,HP- UX,Solaris,Linux) 上缺省是 4MB,但这个上限可以调整到 100MB。也就是说,每段信息应该控制在这个有限长度中。当然,这并不限制WebSphere MQ 用来传递更大的信息,比如文件。

1.2.2队列 (Queue)

我们可以简单地把队列看成一个容器,用于存放消息。队列按其定义可分成本地队列、远程队列定义、别名队列定义、模型队列定义。其中只有本地队列是真正意义上的队列实体,可以存放消息。远程队列定义和别名队列定义只是一个队列定义,指向另一个队列实体。远程队列定义指向的是其它队列管理器中的队列,而别名队列指向的是本地队列管理器中的队列。模型队列有一点特殊,它本身只是一个队列定义,描述了模型的属性,但是当打开模型队列的时候,队列管理器会以这个定义为模型,创建一个本地队列,被称为动态队列。
队列的分类
个队列管理器下辖很多个消息队列,但每个队列却只能属于一个队列管理器。队列在它所属的管理器中只能有一个唯一的名字,不能与同一个管理器的其它队列重名。当消息被添加到队列中,它缺省将被加到最后,与之相反,删除消息缺省却是从头开始。

1.2.2.1本地队列

本地队列按功能又可分为初始化队列,传输队列,目标队列和死信队列。初始化队列用做消息触发功能。传输队列只是暂存待传的消息,在条件许可的情况下,通过管道将消息传送其他的队列管理器。目标队列是消息的目的地,可以长期存放消息。如果消息不能送达目标队列,也不能再路由出去,则被自动放入私信队列保存。
各种队列再消息传送时的作用

1.2.2.1.1普通队列

能够真正长期存放消息的本地队列,我们称之为普通队列。一般说来,应用程序只对其做简单的 MQGET 和 MQPUT 以收发消息,这也是系统中用得最多的消息队列。通常在不致引起混淆的情况下,我们也将普通本地队列简称为本地队列。

1.2.2.1.2传输队列

要送往远地的消息将放入传输队列。在适当的时候,消息会被从传输队列中取出并送往远地,最终放入远端的本地队列。所以,从本地系统的立场来看,传输队列是用来暂时存放输出消息的。

传输队列本身是一个本地队列,它与普通队列的差别是传输队列具有的属性 USAGE (XMITQ)。

1.2.2.1.3初始化队列

初始化队列是配合消息触发用的,如果队列上配置有消息出发功能,则需要指定另一个相关队列以存放触发消息,这个队列就是初始化队列。初始化队列本质上就是一个普通本地队列。

1.2.2.1.4目标队列

在消息通信的时候,消息最终的目的地称为目标队列。如果消息是通过传输队列转发,WebSphere MQ会自动为消息体添加一个传输消息头,其数据结构为MQXQH。其中的RemoteQName和RemoteQMgrName两个域指明了目标队列和目标队列管理器。如果消息被放入死信队列,则WebSphere MQ会自动为消息体添加一个死信消息头,其数据结构为MQDLH,其中DestQName和DestQMgrName两个域指明了原消息的目标队列和目标队列管理器。

1.2.2.1.5死信队列

死信队列本质上是普通的本地队列,由于队列管理器的 DEADQ 属性指定的该队列为死信队列,所以队列管理器认为无法投递的消息都被自动送去该队列。由于无法投递的消息很像信件投递中的死信,故而得名。

队列管理器在将消息放入死信队列的时候,会自动为消息体添加一个死信消息头,其数据结构为 MQDLH。其中 Reason 域指明了消息无法投递的原因。

1.2.2.1.6应答队列

由于消息在发送后需要有对方的回应。这种回应可以是系统自动产生的报告消息,也可以是对方应用生成的应答消息。就应用而言,这些回应消息的目标队列就是应答队列。应答队列通常设置在消息头 (MQMD) 的 ReplyToQ 域中,它也总是与消息头中的另一个域ReplyToQMgr 一起使用。

1.2.2.1.7命令队列

指的是 WebSphere MQ 队列管理器中预定义的 SYSTEM.ADMIN.COMMAND.QUEUE。任何 MQSC 命令都可以送往该队列,并被队列管理器的命令服务器 (Command Server) 接收处理。

1.2.2.2别名队列

别名队列只是一种队列定义,它自身只是队列的逻辑名字,并不是队列实体本身。别名队列的 TARGQ 属性指明了其代表的目标队列名称,目标队列通常是本地队列。其实别名队列只是提供了队列名称之间的映射关系,可以将别名队列看作是指针,指向其目标队列。注意,这里的目标队列自身又可以是一个别名队列,指向下一个目标队列。然而,在对别名队列打开 (MQOPEN) 操作时,只允许别名队列指向的目标队列是一个本地普通队列,即一层映射关系。如果存在上述的多层映射关系,则报错 MQRC_ALIAS_BASE_Q_TYPE_ERROR。

通过别名定义,WebSphere MQ 也可以动态改变消息流向。比如:某程序在代码中指定消息写入队列 A,但是您希望在不变动代码的情况下将消息写入队列 B。这时只要定义别名 B,使之指向 A 即可。再如:某队列 C 是可读可写的本地队列,管理员希望它对于一类程序只可读,对另一类程序只可写,这时可以对 C 定义两个别名 D 和 E,D 只允许读, E 只允许写。也就是说,本地队列 C 的属性为 GET(ENABLED) 且 PUT(ENABLED),将 D 的属性设置为 GET(ENABLED) 且 PUT(DISABLED),E 的属性为 GET(DISABLED) 且
PUT(ENABLED)。将 D 和 E 分别提供给上述两类程序使用,这样可以完全避免应用程序的误操作。

1.2.2.3远程队列

远程队列与别名队列类似,也只是一个队列定义,用来指定远端队列管理器中的队列。使用了远程队列定义,程序就不需要知道目标队列的位置 (所在的队列管理器) 了。

远程队列定义包括目标队列管理器名和目标队列名,而这种队列定义对于访问地的应用程序是透明的。这种技术不但使应用程序只需要对一个简单的队列名操作,而且可以在线地通过修改远程队列定义,而动态改变路由。

1.2.2.4模型队列

模型队列定义了一套本地队列的属性集合,一旦打开模型队列,队列管理器会按这些属性动态地创建出一个本地队列。模型队列的 DEFTYPE 属性可以取值 PERMDYN 和TEMPDYN,分别代表永久动态队列和临时动态队列。

1.2.2.4.1永久动态队列

永久动态队列由模型队列动态创建,并可以永久存在。在调用 MQOPEN 时创建,以后就和普通的本地队列一样工作。在调用 MQCLOSE 时,缺省情况下会保留消息和队列,当然也可以通过设置关闭选项 (Close Option) 的来清除消息甚至删除永久动态队列。

1.2.2.4.2临时动态队列

临时动态队列也是由模型队列动态创建,但只在会话(Session)中临时存在。在调用MQOPEN时创建,在同一个线程中MQCLOSE时关闭并自动删除。MQCLOSE时无所谓关闭选项(Close Option)的取值。

1.2.3队列管理器 (Queue Manager)

队列管理器构建了独立的 WebSphere MQ 的运行环境,它是消息队列的管理者,用来维护和管理消息队列。一台机器上可以创建一个或多个队列管理器,每个队列管理器有各自的名字,通常情况下,它不能与网络中的其它队列管理器重名。如果我们把队列管理器比作是数据库,那么队列就是其中的一张表,消息就是表中的一条记录。

队列管理器是负责向应用程序提供消息服务的机构。在 WebSphere MQ 中,队列管理器集成了对象的定义、配置、管理、调度以及提供各种服务的功能于一身。WebSphere MQ 的系统管理工具提供了对系统部件配置与管理的功能,应用程序必须首先连接到队列管理器,然后在队列管理器的控制下对各种对象进行操作。

WebSphere MQ 中的队列管理器可以含有很多个队列,但一个队列只能属于一个队列管理器。一个操作系统平台可以创建一个队列管理器,也可以创建多个队列管理器。队列管理器、队列、通道等等都是 WebSphere MQ 的对象,所有的对象都有各自的属性,有些属性必须在对象创建的时候指定,有些可以在创建以后更改。

1.2.4通道 (Channel)

通道是两个队列管理器之间的一种单向的点对点的通信连接,消息在通道中只能单向流动。如果需要双向交流,可以建立一对通道,一来一去。站在队列管理器的角度,这一对通道可以按消息的流向分成输入通道和输出通道。通过配置,对于放入本地传输队列中的消息, 队列管理器会自动将其通过输出通道发出,送入对方的远程目标队列。

两个队列管理器之间可以有多条通道负责传输不同的内容,这样设计往往是为了将不同优先级的消息错开,运行于不同速率的网络连接上。或者即便是所有通道都运行于相同的网络物理连接上,也可以将不同大小的消息传送分开,以免小数据传送被大文件所堵塞。如果多条通道共享一条网络物理连接,通道的速率之和受限于网络速度。这样可以增加传送的并发度但并不能增加整体的传送速度。

在通道上可以配置不同的通信协议,这样就使得编程接口与通信协议无关。通道两端的配置必须匹配,且名字相同,否则无法连通。队列管理器之间的通信是通过配置通道来实现的,通道两侧的队列管理器对这个通道的相关参数应该能对应起来,一个通道只能用一种通信协议,但不同的通道可以有不同的通信协议。可见,通道是架设在通信协议之上的对象, 架设在不同通信协议上的通道在应用层看来都大同小异。

1.2.4.1通道类型 (Channel Type)

WebSphere MQ 用通道类型属性 (CHLTYPE) 约定了通信双方在连接握手协议中的主动方和被动方以及应用消息的流向。可选以下这些类型:
 SDR Sender。握手协议的主动方,消息的发送方
 RCVR Receiver。握手协议的被动方,消息的接收方
 SVR Server。在握手协议中可以是主动方也可以是被动方,消息的发送方
 RQSTR Requester。在握手协议中可以是主动方也可以是被动方,消息的接收方
 CLNTCONN Client Connection。在 Client-Server 连接时,定义客户端连接定义表(Client Channel Definition Table) 时使用。握手协议的主动方,消息的发送方
 SVRCONN Server Connection。在 Client-Server 连接时,定义服务器端连接时使用。握手协议的被动方,消息的接收方
 CLUSSDR Cluster Sender。在群集中发送配置信息和应用消息。握手协议的主动方,消息的发送方
 CLUSRCVR Cluster Receiver。在群集中接收配置信息和应用消息。握手协议的被动方,消息的接收方

通信双方的通道类型配对并不是可以随意排列组合的,共有六种。

通道类型的配对
图中细线箭标表示握手协议中的主动连接,粗线箭标表示应用消息流向。消息在所有的通道上都是单向传送的。
 Sender/Receiver 是所有连接中最简单、最常用的一种。Sender 是通道主动方,也是消息发送方。
 Requester/Server 也是常用的一种连接方式。Requester 是通道主动方,但通道连接
后,它作为消息接收方,Server 是消息发送方。
 Server/Receiver 与 Sender/Receiver 类似,Server 是消息的发送方,也是连接的主动方。与 Sender 定义类似,Server 定义中必须指定 CONNAME 参数。
 Sender/Requester 的连接过程稍微复杂一些,Requester 首先与 Sender 连接,在通知对方连接参数后连接断开。Sender 进行反向连接,消息也是反向传送的。这种反向连接的方式,称为 Callback Connection。
 Sender Connection/Receiver Connection 与 Sender/Receiver 方式相同 。 用于
Client/Server 之间的 MQI 通道。
 Cluster Sender/Clueter Receiver 与 Sender/Receiver 方式相同。用于群集中队列管理器之间的连接。

由于 Sender/Receiver、Server/Receiver 的连接主动方和消息发送方相同,所以可以在发送端设定通道触发 (Channel Trigger)。
由于 Sender/Receiver、Server/Receiver、Requester/Server 的连接被动方事先不需要知道主动方的连接参数,所以可以用于连接主动端是动态地址的应用场合。
由于 Sender/Requester 有反向建立连接的功能,所以常常用于双向安全认证。

1.2.4.2消息通道协议 (MCP)

消息通道协议是 WebSphere MQ 用来传递消息时使用的通信协议。MCP (Message Channel Protocol) 可使用多种底层通信协议传递消息(LU6.2, DECNet …)。消息通道协议使得消息的传送独立于通信协议,应用程序通过统一的接口与 MQ 打交道,而不再需要关心通信层使用的是TCP/IP 还是SNA。目前 MCP 支持的通信协议有LU6.2、DECNet 和TCP/IP。

1.2.4.3消息通道代理 (MCA)

消息通道代理 (MCA,Message Channel Agent) 本质上是一个通信程序,它用来在队列管理器之间传递消息。通道可以以进程的方式工作,即独立的 MCA 进程。也可以以线程的方式嵌入系统 MCA 进程中工作。对于前者,根据不同的 MCP,发送端进程和接收端进程的 MCA 名通常是不同的。

1.3工作原理

WebSphere MQ 的工作原理的核心就是存储转发。在单个队列管理器的环境中,队列可以用于存储应用间传递的消息,从而使应用程序在各自环节上进行处理,并通过队列形成环环相扣的处理流程。在多个队列管理器的环境中,消息可以跨平台进行流动,从而使整个处理流程在分布式计算环境中完成。

1.3.1 PUT 和 GET

WebSphere MQ 的应用程序可以通过 MQ 界面 (MQI,MQ Interface) 进行操作。实际上, MQI 提供了有限的 API,其中最本质的两个动作是 PUT 和 GET。PUT 指应用程序放一条消息放入到队列中,GET 则相反,应用程序将一条消息从队列中取出。WebSphere MQ 通过队列机制来完成消息排队和传递的工作,从而使应用程序之间实现松耦合的联系。如下图,应用程序 A 产生消息,通过 PUT 调用放入队列中,应用程序 B 将消息取出并进行相应的处理, 消息的报文格式及内容决定了应用程序 B 处理的具体工作。这样就实现了应用程序 A 到 B 之间的单向消息传递,如果需要双向传递消息则必须再类似地约定反向队列。
应用通过队列传送消息

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值