一、中间件
MQ是一种中间件产品,至于什么是中间件,中间件能干什么,参见以下链接:
http://baike.baidu.com/view/23710.htm
二、WebSphere MQ的原理
Websphere MQ是IBM的商业通讯中间件(Commercial Messaging Middleware)。Websphere MQ提供一个具有工业标准、安全、可靠的消息传输系统。它的功能是控制和管理一个集成的商业应用,使得组成这个商业应用的多个分支程序(模块)之间通过传递消息完成整个工作流程。Websphere MQ基本由一个消息传输系统和一个应用程序接口组成,其资源是消息和队列(Messagingand Queuing)。
消息:消息就是一个信息单元,这个信息单元可以是一个请求(Request message),也可以是一个应答(Reply message),或者是一个报告(Report message)或一份报文(Datagram messge)。一个消息包含两个因素——消息描述(用于定义诸如消息传输目标等)和数据消息(如应用程序数据或数据库查询等)。程序之间的通信通过传递消息而非直接调用程序。
队列:一个安全的存储消息的地方,消息的存储一般是顺序的,队列是消息分阶段地传送和接收。因为消息存放在队列中,所以应用程序可以相互独立的运行,以不同的速度,在不同的时间,在不同的地点。
消息传输系统:用于确保队列之间的消息提供,包括网络中不同系统上的远程队列之间的消息提供。并保证网络故障或关闭后的恢复。
应用程序接口:应用程序和消息系统之间通过Websphere MQ API实现的接口Websphere MQ API在所有Websphere MQ平台上是一致的。API只有14个调用,2个关键动词:发送(PUT)和接收(GET)。
三、WebSphere MQ的重要特点
3.1 统一接口
跨越IBM和非IBM平台。简单的PUT和GET动词在WebSphere MQ支持35种IBM和非IBM平台上完全相同。使得WebSphere MQ提供了这样的特性:目标应用程序位置的透明性(targetapplicationlocationtransparency)。对于一个应用程序的开发者,他需要知道的全部只是队列的名字,这个队列与一个特定的服务有关,而与系统的平台或系统在什么地方无关。
使开发人员避开网络的复杂性。因为WebSphere MQ负责处理所有的通讯,开发人员不必编写任何通讯方面的程序。并且编程和调试非常简单和直接,不需要具体的系统和通讯方面的知识。尤其在开发客户机/服务器模式的应用时,开发人员可以集中精力在与业务有关的客户端和服务器端的应用,而不必考虑操作系统和通讯,特别是底层的网络通讯,节省大约50%到75%of通讯编程工作。
3.2 处理不依赖时间的限制
意思是说在信息创建和发送时,信息的接收方或到接收方的通道不需要激活.不受时间的限制增加了处理的灵活性,允许事务处理在它们想做或有时间做时。彼此通讯程序可以运行在不同的时间。这样程序的运行是独立的,如果逻辑允许,它们不必等待其它程序的应答而继续工作,利用这种异步处理功能,可以更有效的使用资源,更灵活的处理模式,应用处理可以是独立的,并行的,重叠的,从而改进用户服务。
3.3 给分布式处理提供的强健的中间件
包括逻辑工作单元支持(logicalunitofwork),备份和恢复机制,大信息传递和高性能等特点。其中最重要的是确保信息传输,意思是一旦WebSphere MQ接受一个信息传输的任务,会确保信息被传送到目标平台。信息的传输是一次且仅一次.另外,强健的中间件机制保证业务数据一致性,并可在系统发生故障时,及时恢复,业务不会受到影响。
四、MQ的基本概念
4.1 WebSphere MQ对象(objects)
WebSphere MQ对象是一种由WebSphere MQ管理的具有可恢复能力的资源。
队列管理器(Queue managers)
队列(Queues)
名字列表(Namelists)
分发列表(Distribution lists)
进程定义(Process definitions)
通道(Channels)
存储类(Storage classes)
这些对象在异种平台上都是统一的。对于系统管理员来说,操纵对象的命令都是可用的。这些命令格式,对于不同平台是有区别的。当你创建队列管理器时,会自动地创建缺省对象。这些缺省对象可以帮助您来定义所需的对象。
每一个对象都有一个名字,以便通过命令和MQI调用可以引用它。通常在这些对象类型中的每一种对象的名字必须唯一。例如,一个队列和一个进程的名字可以相同,但是不可以有两个相同名字的队列。这意味着一个本地队列名不能和模板队列、远程队列或别名队列相同。但是也会有些特殊情况。另外在互连的队列管理器网络中,队列管理器名必须唯一。
WebSphereMQ的对象名是大小写敏感的,因此在定义对象时,需要仔细选择好大小写字母。在 WebSphere MQ 中,除最多有 20 个字符的通道之外,名称最多可以有 48 个字符。
4.2 消息
消息是对使用它的应用程序有意义的以字节为单位的字符串。消息可以用来实现在相同或不同平台上应用程序间的通信。
WebSphere MQ 消息由两个部分:
应用程序数据。
应用程序数据的内容和结构由使用它的应用程序定义。
消息描述符。
消息描述符标识消息,并包含其它控制信息,如消息类型和消息的优先级,消息描述符的格式由 WebSphere MQ 定义。
WebSphere MQ定义了四种基本类型的消息。应用程序可以定义其他类型的消息。四种基本类型是:
请求消息 Request message
请求消息需要应答。从客户端发往服务器的查询和更新信息往往是一条请求消息。请求消息中应该包含回复消息的路由信息,即回复消息发往什么地方。
回复消息 Reply message
回复消息是对请求消息的回应。请求消息中的信息决定了回应消息的目的地。处理请求和回应的应用程序控制着消息间的关联,这种关联和队列管理器没有关系。消息自身带有足够的信息供应用程序实现这种关联。
报文消息 Datagram message
数据报消息是不需要回复的消息,报文消息只是一次单向的信息传送。
报告消息 Report message。
报告消息用于对一些系统故障的响应。有些报告消息是由应用程序创建的,有些报告消息是由队列管理器创建的。后一种情况是由于远程队列已经满或者远程队列不存在引起消息不能正确发送。最初发送这条消息的应用程序不能检测到这种错误,只有等远程队列管理器创建了这样一条报告消息并发往本地队列管理器之后,应用程序才能作相应的处理。
队列管理器把报告消息也用于其他目的,比如报告一些事件。消息可能有一个失效时间限制。如果一条消息在失效时间过后还没有被某个应用程序处理,该条消息将被队列管理器从系统中清除。当队列管理器清除一条失效消息之后,它将创建一条报告消息,这条报告消息的目的地址由失效消息提供。
报告消息的另一个用途是确保消息的到达。应用程序可以要求它们所发送的消息到达目的地后,他们收到一条报告消息,这叫做接收确认(Confirmation of arrival)。与此相类似,应用程序也可以要求当另外一个程序取走这条消息时它们收到一条报告消息,这被叫做交付确认(Confirmation of delivery)。这两种情况,都是由队列管理器创建报告消息,并把报告消息发送到适当地目的地。
另外还一类特殊的消息叫触发消息。触发消息是由队列管理器创建的一类特殊消息。WebSphere MQ的队列管理器提供了一种当满足某一条件时,自动触发应用程序的机制,而触发消息是触发机制的重要组成部分。
应用程序也可以定义新的消息类型。队列管理器不能解释这些类型,应用程序设置的消息类型由一个范围。这些类型值可用来区分不同类型的应用程序在同一个输入队列中放入的消息。
消息长度
最大消息长度为 100 MB(其中 1 MB 等于 1 048 576 字节),缺省最大消息长度是 4 MB。实际上,消息长度受以下方面的影响:
- 接收队列定义的最大消息长度
- 队列管理器定义的最大消息长度
- 传输队列定义的最大消息长度
- 发送或接收应用程序定义的最大消息长度
- 存储消息的可用空间
所以有时可能需要由多个消息组成的信息才能满足应用程序的要求。
4.3 队列
队列是用于存储消息的数据结构,目前WebSphere MQ 版本 5.3 支持超过 2 GB 大小的队列。
4.3.1 队列的类型
按创建方法分类
- 预定义队列由管理员使用相应的 MQSC 或 PCF 命令创建。 预定义队列是永久的;它们的存在与应用程序是否使用它们无关,并且 WebSphere MQ 重新启动后继续存在。
- 动态队列在应用程序发出设定模型队列名的MQOPEN调用时创建的。被创建的队列是基于一个模板队列。 您可以使用 MQSC 命令 DEFINE QMODEL 创建模板队列。动态队列继承了模板队列的属性。模板队列有一个属性可以说明动态队列是永久的还是临时的。永久队列在应用程序和队列管理器重新启动后继续存在;临时队列在重新启动后消失。
按功能分类
1. 本地队列(local queue):
一个本地队列是一个物理上位于本地队列管理器中的队列。本地队列实际上存在与本地系统的内存或磁盘存储终。本地队列管理器控制队列的访问。应用程序可以“PUT”消息到本地队列,也可以从本地队列“GET”消息,另外程序还可以查询或修改这些队列的某些属性。对队列属性的修改需要相应的权限。
2. 远程队列(remote queue):
一个远程队列属于一个不与该应用程序直接相连的队列管理器。对这类队列的访问包含有本地队列管理器和远程队列管理器的通信过程。这种通信涉及到通道。 应用程序可对远程队列进行某些操作,比如程序可以向一个远程队列放一条消息,但程序不能从远程队列中去消息。应用程序只能从本地队列读取消息。
应用程序有两种不同的方法可用来访问远程队列。第一种是当程序打开一个远程队列时同时提供队列管理器名和队列名两个参数。这要求程序知道目的队列属于哪个队列管理器。第二种方法是在本地队列管理器上存在一个远程队列的定义,这个定义包含有足够的信息让本地队列管理器确定该远程队列所在的队列管理器。远程队列定义中的目的队列不一定是远程队列管理器的本地队列,它也可以是一个远程队列定义。(这就话和之后的网关队列管理器的创建有关系)
应用程序放一条消息到Q1,Q1是本地队列管理器QM1上的一个远程队列定义:Q2at QM2。QM2是远程队列管理器。Q2是QM2上的一个远程队列定义Q3 at QM3。Q3是QM3的一个本地队列,经过两次传送,消息最终到达Q3这个QM3的本地队列。
有多种原因使这种多跳(Multihop)传送变得有意义。在一个TCP/IP网络内部,所有机器都有IP地址,IP协议本身处理节点间的路由选择。但假设消息需要穿过不同类型的网络,这就需要中间件参加路由选择。在图中,QM2位于一台连接TCP/IP网和SNA网的机器上,只需在QM2上提供一个远程队列定义Q2:Q3 at QM3,就可以实现消息的跨网络传输。
因为对远程队列的访问总是涉及到队列管理器之间的通信,因而我们需要定义其他一些资源,比如通道、传输队列(Transmission queue)。
3. 传输队列(Transmission queue):
传输队列是临时存储目标为远程队列管理器的消息的队列。队列管理器利用传输队列把消息分阶段地发向远程队列。队列管理器和消息移动程序一起负责把数据传送到远程队列。当队列管理器收到把一条消息发往远程队列的要求后,它把消息发送到一个与目的队列管理器相关联的传输队列,传输队列位于本地队列管理器上。目的队列管理器的名称可能由应用程序提供,也可以从远程队列定义中得到。
一个传输队列是两个队列管理器之间的连接的一端。所有直接目的地是同一队列管理器的消息都可放在同一个传输队列上,这些消息的最终目的可能不一样。把消息从一个队列管理器传送到另一个队列管理器只需要一个传输队列,然而也有可能在两个队列管理器之间存在着多个连接以提供不同的传输服务,每个连接都带有一个不同的传输队列。
传输队列是由MCA处理的,MCA负责在队列管理器之间可靠地传送消息。MCA实际上是处理传输队列上消息的MQI应用程序。
4. 动态队列和模板队列:
除了有固定定义的队列之外,WebSphere MQ还为程序在它们执行时提供了动态地创建队列的能力。例如,一个应用程序作为某种服务的客户,它可能创建一个动态队列,并通知服务器把对服务要求的响应发送到该动态队列。当然,这种情况也可以使用具有永久定义的队列。为了简化在创建动态队列时所必需设置的许多参数,动态队列总是基于模板队列被创建的,模板队列定义了动态队列的所有属性。当应用程序试图打开一个模板队列时,WebSphere MQ就创建一个动态队列。WebSphere MQ为应用提供了系统模板队列。
动态队列也可以分成两种,它们的生存周期和故障恢复特性不同。在创建临时动态队列(Temorary dynamic queue)的应用程序关闭时,这些队列将被删除,队列上的消息将丢失。这类动态队列不支持消息的持久性。如果队列管理器发生故障重新启动,临时动态队列也不会被恢复。另一种动态队列是持久动态队列(Permanent dynamic queue)。只有当一个应用程序关闭持久动态队列时定义删除选项,持久动态队列才会被删除。删除持久动态队列的程序不一定是创建持久动态队列的程序,持久动态队列在队列管理器重启后会被恢复,并且支持具有持久性的消息。
5. 启动队列
启动队列是在触发中使用的队列。如果队列管理器将使用触发,则必须至少为此队列管理器定义一个启动队列。队列管理器在触发器事件发生时将触发器消息放入启动队列。触发器事件是由队列管理器检测的条件的逻辑组合。例如,当队列上的消息数达到预定义深度时,可能会生成触发器事件。此事件使队列管理器将触发器消息放入指定的启动队列。此触发器消息由触发器监视器(即监视启动队列的特殊应用程序)检索。然后触发器监视器启动在触发器消息中指定的应用程序。
6. 群集传输队列
每个在群集中的队列管理器有一个称为 SYSTEM.CLUSTER.TRANSMIT.QUEUE 的群集传输队列。当您定义队列管理器时,按缺省情况创建此队列的定义。作为群集一部分的队列管理器可以将群集传输队列上的消息发送到在同一群集中的任何其它队列管理器。 在路由解析期间,群集传输队列优先于缺省传输队列。 当队列管理器是群集的一部分时,缺省操作是使用 SYSTEM.CLUSTER.TRANSMIT.QUEUE,除非当目标队列管理器不是此群集的一部分。
7. 死信队列 (Dead letter queue)
死信(未传递的消息)队列是存储无法发送到其正确目的地的消息的队列。有时候会出现队列管理器不能把消息发送到目的地的情况,此时消息将被发送到某个死信队列中。死信队列中的消息常常暗示了系统可能出现的问题。例如当一条消息到达目的队列管理器之后却发现目的队列并不存在。或者目的队列出现不能接收信消息的情况,比如目的队列已经满了,或者它被设置成不允许再加入新的消息。并不是所有的放消息操作的失败都导致消息被放入死信队列,例如,由于本地队列出现错误造成应用程序不能“放”消息,此时MQI调用直接把错误码返回给应用程序。
有些错误只能由死信队列报告,例如,一条消息穿越网络之后到达目的队列管理器,却发现目的队列已满。发现错误的机器不同于最初“放”消息应用程序所在的机器,甚至可能放消息的应用程序已不在运行状态。此时目的队列管理器把这条消息发往它所拥有的死信队列,而不是简单地扔掉该条消息。这样使得这次错误是可见的,也给应用程序提供了一个改正错误的机会。
死信队列是WebSphere MQ面对远端系统错误时的一种解决方案。应用程序可以利用WebSphere MQ提供的其他一些工具来监视并确保消息的可靠传送和接收。
在队列管理器创建时,系统会缺省创建一个死信队列,队列名是SYSTEM.DEAD.LETTER.QUEUE。建议在生产系统上,需要独立创建一个死信队列,而不使用系统缺省的死信队列。
8. 命令队列
命令队列 SYSTEM.ADMIN.COMMAND.QUEUE 是用来存放由应用管理程序放的具有PCF(programcommand format)的消息的队列。该队列主要用于编写管理程序时使用。具体的使用将在后续章节介绍。在创建队列管理器时将为每个队列管理器自动创建命令队列。
9. 回复队列
当应用程序发送请求消息时,接收消息的应用程序可以将回复消息发送给发送应用程序。此回复消息放入一个称为回复队列的队列中,它通常是发送应用程序的本地队列。回复队列的名称由作为消息描述符一部分的发送应用程序指定。
10. 别名队列
别名队列实际上是本地队列、远程队列定义或队列名表的另外一个名字。它是一种简单的名字到名字的映射,它允许应用程序用另外一个名字来访问队列。WebSphere MQ已经为应用程序屏蔽了许多底层系统细节,特别是网络通信的细节,而别名队列允许在不修改应用程序的条件下访问其他名字的队列。
4.4 队列管理器
在WebSphere MQ中队列管理器是基本的软件系统,队列管理器可看成是队列和其他对象的容器。WebSphere MQ中的每一个队列都属于一个队列管理器,队列管理器是为应用程序和WebSphere MQ部件(一些管理工具)提供对队列管理中对象的访问。
一个队列管理器是WebSphere MQ中的一个基本的独立的执行单元。一台机器上可以运行一个或多个队列管理器。
任何需要访问WebSphere MQ提供的服务的应用程序都必须先和队列管理器相连,和应用程序相连的队列管理器对该应用程序而言就叫“本地队列管理器”(Local Queue Manager),本地队列管理器为程序提供MQI调用的支持。应用程序可以操作、管理本地队列管理器所拥有的各种资源,也可以向其他的队列管理器发送消息。
应用程序通过一种叫做MQI的编程接口向队列管理器申请服务。这些服务包括“放”一条消息到队列或从队列“取”一条消息等一些基本操作。队列管理器还使队列成为可靠的存储消息的地方,它也控制安全性管理,并提供一些特殊的队列功能,比如触发队列。
为了减少应用程序对于它所运行环境的依赖性,WebSphere MQ的应用程序可以和一个它不知道名字的队列管理器相连,这个队列管理器就是一台机器上的缺省队列管理器。如果程序在调用MQCONN时,把队列管理器名参数设置为空,MQCONN将返回与缺省的队列管理器连接的句柄。
队列管理器拥有每个队列。队列管理器负责维护它所拥有的队列,以及将它接收到的所有消息存储到相应的队列。可以由应用程序或队列管理器将消息放入队列,这些是它的正常操作的一部分。
4.5 通道
消息通道(Message channels)
消息通道是一种提供从一个队列管理器到另一个队列管理器的通信路径。消息通道用在分布式的队列把消息从一个队列管理器发送到另一个队列管理器。它们使应用程序屏蔽了底层的通信协议。队列管理器可能存在同种或异种平台之间。为了实现队列管理器之间的通信,您必需在一个队列管理器中定义一个发送消息的通道对象,在另一个队列管理器中定义一个接收消息的通道对象。消息通道是一个单向链接。它通过消息通道代理(message channel agents)把两个队列管理器连接起来。
消息通道的定义可以分为以下6种类型:
发送通道(Sender)
接收通道(Receiver)
服务器通道(Server)
请求器通道(Requester)
群集发送通道(Cluster sender)
群集接收通道(Cluster receiver)
消息通道的组合形式
如果要在队列管理之间实现消息传输,必须要在两个队列管理器上都要定义相应的通道。发送方和接收方通道的组合形式如下:
发送通道-接收通道(Sender-receiver )
请求器通道-服务器通道(Requester-server)
请求器通道-发送通道(Requester-sender (callback) )
服务器通道-接收通道(Server-receiver )
群集发送通道-群集接收通道(Cluster sender –cluster receiver)
消息通道用法
发送通道-接收通道(Sender-receiver)
用法:由一个系统的发送通道来启动通道,以便它可以发送消息到另一个系统。发送通道向接收通道发送启动请求。发送通道从传输队列发送消息到接收通道。接收通道把消息放到目标队列。
请求器通道-服务器通道(Requester-server)
用法:
(1)由一个系统中的请求器通道来启动通道,以便它能从另一个系统接收到消息。 请求器通道向通道另一端的服务器通道发送请求来启动。服务器通道从传输队列把消息发送到请求器通道。
(2) 服务器通道也能启动通道,并发送消息到请求器, 但这仅应用于完全意义的服务器通道, 也即服务器通道定义中应含有对方的连接名。一个完全意义的服务器通道可以由请求器通道启动, 也可以发起和服务器通道的通讯。
(3) 最好不要手工去停止Server和Request通道,而是依靠Server通道的Discint的属性来停止通道。
请求器通道-发送通道(Requester-sender (callback)
用法:请求器通道启动通道,发送通道终止这个会话。发送通道然后依据它的通道定义中的信息(称为 callback)来重新启动会话。它把消息从传输队列发送给请求器通道。最好不要手工去停止Sender和Request通道,而是依靠Sender 通道的Discint属性来停止通道。
服务器通道-接收通道(Server-receiver)
用法:类似于发送通道
群集发送通道(Cluster sender)
用法:在一个群集中,每个队列管理器都有一个群集发送通道,通过它可以把送群集信息发送到其中一个队列管理器资源管理器。 队列管理器通过这个通道也可以把消息发送到其他的队列管理器。
集接收通道(cluster receiver)
功能:在一个群集中,每一个队列管理器都有一个群集接收通道。通过这个通道可以接收数据消息和关于群集的消息。
MQI通道
MQI通道是WebSphere MQ 客户端和服务器上的队列管理器的通信的通道。当客户端应用程序发出MQCONN或MQCONNX调用时,才开始建立连接。它是一个双向的通道,可以负责发送和接收,被用作MQI调用的传送和响应。一个MQI通道可以把一个客户端连接到单个队列管理器,MQI通道有两种类型,它们定义了双向的MQI通道。