最近在学习MQ的知识,看了很多东西,回过头来觉得应该把MQ的基本概念加深一下认识,所以把一些基本的概念总结了出来。
有关消息的概念:
1. 消息包括两部分:
Ø 从一个程序传递到另一个程序的数据部分
Ø 消息描述符或叫消息头
消息描述符定义了MessageID、控制信息(包括如:消息的类型、终结时间、correlationId、优先级、以及等待应答的队列名字)。
消息的长度可以从4M~100M,取决于使用的MQSeries的版本。
2. 消息片断和分组:
在MQSeries5中支持消息的分片和分组。如果允许,队列管理器把不适合队列的消息自动分片。在接受端,程序可以通过接受分片来获得整个消息。
第二种分片是应用程序根据物理边界和缓存大小来对消息进行分片。程序把每一个片断作为独立的物理消息,多个物理消息构成一个逻辑消息。队列管理器会保证分片的次序。
为了减少网络传输的时间,也可以把多个小分片组成一个大的物理消息。消息被发送到目的地,并在那里被拆解回小的分片。
3. 发送列表:
使用MQSeries5,你可以利用一次MQPUT调用来把消息发送到一个或多个目的队列。这是通过动态发送列表来完成的。发送列表可以是一个文件,在程序启动的时候读取该文件。该文件可以在任何时候被修改。该文件包含一个列表,该列表保存队列的名字和拥有该队列的队列管理器的名字的对应关系。消息发送到具有相同队列管理器的多个队列的时候,该消息在网上实际只被传输一次,以便减少网络传输。接受的队列管理器复制该消息,并把它们发送到其他的目的队列上。这个功能称作:Late fan-out。
4. 消息的类型:
Ø 请求消息(Request Message):请求消息需要应答。从客户端发往服务器的查询和更新消息往往是一条请求消息。请求消息中应该包含回复消息的路由信息。即回复消息发往什么地方。
Ø 回复消息(Reply Message):回复消息是对请求消息的回应。请求消息中的信息决定论了回应消息的目的地。处理请求和回应的应用程序控制着消息间的关联,这种关联和队列管理器没有关系。消息自身带有足够的信息供应用程序实现这种关联。
Ø 报文消息(Datagram Message):数据报消息是不需要回复的消息,报文消息只是一次单向的信息传递。
Ø 报告消息(Report Message):报告消息用于对一些系统故障的响应。有些报告消息是由应用程序创建的,有些报告消息是由队列管理器创建的。后一种情况是由于远程队列以满或者远程队列不存在引起消息不能正确发送。最初发送消息的应用程序不能检测到这种错误,只有等待远程队列管理器创建了这样一条报告消息并发往本地队列管理器之后,应用程序才能做相应的处理。
5. 持久性消息和非持久性消息:
如果一个消息在任何情况下都必须发送到目的地就是持久性消息。如果一个消息不能准时到达目的地时可以被丢弃,就是非持久性消息。传递持久性消息的时候要记录log,以便系统故障时恢复,非持久性消息在重起后不能被恢复。
6. 消息描述符:
下表包含一些消息描述符的属性字段,它们能够说明一些由队列管理器提供的功能。
7. 队列管理器:
MQSeries的核心是队列管理器(简称,MQM)。队列管理器的工作是管理程序中要使用的队列和消息。它为程序提供用来通信的MQI(Message Queuing Interface)。程序通过API调用来获得队列管理器提供的功能。例如,MQPUT API调用来把消息放到队列中,而另一个程序通过MQGET API调用来从中读取消息。如下图所示。
程序不但可以把消息通过队列管理器发送到运行在同一个机器上的另一个应用程序,也可以发送到运行在远程系统上的应用程序。远程系统拥有自己的队列管理器和队列。如下图所示。
利用现有的网络协议,如TCP/IP、SNA或SPX,一个队列管理器通过通道把消息发送到另一个队列管理器。同一机器上的多个队列管理器之间的通信也需要使用通道。
8. 队列管理器的集群:
MQSeries for MVS/ESA以及针对分布式平台的5.1版提供可以把多个队列管理器集群的功能。形成集群的队列管理器可以运行在相同的机器上,也可以运行在不同平台下的不同机器上。通常,利用维护一个仓库,这个仓库包含所有队列管理器以及队列的信息。维护仓库的工作由集群的队列管理器中的一个来完成。另外还需要一个队列管理器来维护一个局部的仓库,这个仓库用来维护一些对象。仓库允许集群内的任意队列管理器来查找有关的集群队列以及谁拥有该队列。队列管理器使用特殊的集群通道来交换信息。
集群允许一个队列有多个实例(具有相同名字的队列),这些队列分布在不同的队列管理器中。考虑到均衡工作量,队列管理器可以把消息发送到一个应用程序的多个实例中。
在通常的分布式处理过程中,我们把消息发送到指定的队列管理器拥有的指定的队列中。所有的消息由队列管理器发送到处在发送端的发送队列中。这个传输队列具有与目的队列管理器相同的名字。消息通道代理通过网络传递消息,并把消息放到目的队列中。下图说明了传输队列(Xmit Queue)与目的队列管理器的关系。
在集群中,你可以把消息发送到集群中的指定名字的队列,在下图中用云朵表示。你需要指定目标队列的名字,而不需要指定远程队列定义的名字。集群不必有远程队列定义。对于当你把消息发送到不是集群成员的队列管理器中,这是很有用的。你也可以指定队列管理器并直接把消息发送到明确的队列,但是通常这些都留给队列管理器来决定,队列在什么地方以及发送到哪个队列。
MQSeries集群表现为一个队列的多个实例共存的地方。消息的流动按照管理员的要求,以便使用变化的可用性和吞吐量的需求。以上的过程都是动态完成的,不必对管理器进行复杂的配置和控制。另外,开发人员不必考虑过多的队列,对他们来说就像是在向一个单独的队列些消息。
MQ发布消息时通过循环发送来完成的。你也可以改变这种默认的行为。下图,消息要发送到3个位于集群中名字为A的队列。这三个队列管理器都包含一个名字为A的队列。默认情况下,消息的发送顺序为:先是队列管理器1中的QA,然后是队列管理器2中的QA,再是队列管理器3中QA,再循环到队列管理器1中的QA。
另一种情况,如果第三个队列管理器down掉,并且第三个QB的实例不可用。由于消息会被发送到所有的队列管理器和想要达到的队列,所以发送方的队列管理器会意识到问题。当消息只能被发送到前两个实例时,发送的队列管理器就知道第三个队列的实例有问题。这时,有关集群有问题的特殊消息会被发送到所有的队列管理器。