Message Queues
文档
(MicroSoft Message Queue
,微软消息队列
)
一、
基本概念
MSMQ
是在多个不同的应用之间实现相互通信的一种异步传输模式,相互通信的应用可以分布于同一台机器上,也可以分布于相连的网络空间中的任一位置。用于创建分布式、松散连接的消息通讯应用程序的开发工具。
消息队列和电子邮件有着很多相似处,他们都包含多个属性,用于保存消息,消息类型中都指出发送者和接收者的地址;然而他们的用处却有着很大的区别:消息队列的发送者和接收者是应用程序,而电子邮件的发送者和接收者通常是人。如同电子邮件一样,消息队列的发送和接收也不需要发送者和接收者同时在场,可以存储在消息队列或是邮件服务器中
二、
实现原理
消息的发送者把自己想要发送的信息放入一个容器中(我们称之为
Message
),然后把它保存至一个系统公用空间的消息队列
(Message Queue)
中;本地或者是异地的消息接收程序再从该队列中取出发给它的消息进行处理
三、
术语解释
1.
消息
消息是由通信的双方所需要传递的信息。它可以是各式各样的媒体,如文本、声音、图象等等。
消息最终的理解方式,为消息传递的双方事先商定,这样做的好处是,一是相当于对数据进行了简单的加密,二则采用自己定义的格式可以节省通信的传递量。
消息可以含有发送和接收者的标识,这样只有指定的用户才能看到只传递给他的信息和返回是否操作成功的回执。消息也可以含有时间戳,以便于接收方对某些与时间相关的应用进行处理。消息还可以含有到期时间,它表明如果在指定时间内消息还未到达则作废,这主要应用与时间性关联较为紧密的应用。
2.
队列
队列是发送和接收消息的公用存储空间,它可以存在于内存中或者是物理文件中。
两种主要的队列类型:由您或网络中的其他用户创建的队列和系统队列。用户创建的队列可能是以下任何一种队列:
1.
公共队列
在整个“消息队列”网络中复制,并且有可能由网络连接的所有站点访问
2.
专用队列
不在整个网络中发布。相反,它们仅在所驻留的本地计算机上可用。专用队列只能由知道队列的完整路径名或标签的应用程序访问
3.
管理队列
包含确认在给定“消息队列”网络中发送的消息回执的消息。指定希望
MessageQueue
组件使用的管理队列(如果有的话)
4.
响应队列
包含目标应用程序接收到消息时返回给发送应用程序的响应消息。指定希望
MessageQueue
组件使用的响应队列(如果有的话)
四、
使用优势
1.
由于是异步通信,提高了事物处理的能力
采用消息传递机制,发送方不必要再担心接收方是否启动、是否发生故障等等非必要因素,只要消息成功发送出去,就可以认为处理完成,而实际上对方可能甚至未曾开机,或者实际完成数据处理时可能已经是第二天了。
2.
当信息传送过程中,信息发送机制具有一定功能的故障恢复能力
消息可以以两种方式发送,即快递方式
(express)
和可恢复模式(
recoverable
)
,
它们的区别在于,快递方式为了消息的快速传递,把消息放置于内存中,而不放于物理磁盘上,以获取较高的处理能力;可恢复模式在传送过程的每一步骤中,都把消息写入物理磁盘中,以得到较好的故障恢复能力。
3.
数据传送可靠性
消息队列可以放置在发送方、接收方所在的机器上,也可以单独放置在另外一台机器上。正是由于消息队列在放置方式上的灵活性,形成了消息传送机制的可靠性。
4.
消息通信的双方具有不同的物理平台成为可能
队列只是一个存储消息的容器,只要具有相应的操作系统权限,就可以通过任何的应用程序进行读取写入
五、
实现对
MSMQ
的操作
在
.NET
产品中,提供了一个
MSMQ
类库
“System.Messaging.dll”
。它提供了两个类分别对消息对象和消息队列对象进行操作。在能够使用
MSMQ
功能之前,你必须确定你的机器上安装了
MSMQ
消息队列组件,并确保服务正在运行中。
1.
创建队列
string
mq_name = "机器名称/队列名称"
System.Messaging.MessageQueue.Create(@mq_name);
2.
发送消息
MessageQueue mq = new MessageQueue(mq_name);
mq.Send(Msg);
其中:
Msg
为任一对象。
3.
接收消息
消息的接收又分成同步和异步方式两种,同步接收在规定时间内从消息队列中取出收到的第一条消息,当消息队列中没有消息时,程序处于等待状态;异步接收方式则是定义了一个事件处理函数,当消息队列中第一个消息到达时立即触发该函数。
1.
同步方式
MessageQueue mq = new MessageQueue(mq_name);
string[] types = { "System.String" };
((XmlMessageFormatter)mq.Formatter).TargetTypeNames = types;
Message m=mq.Receive(new TimeSpan(0,0,3));
Label1.Text = (string)(m.Body);
首先定义收到消息应转换成的格式,然后在指定时间内去接收消息
2.
异步方式
MessageQueue mq = new MessageQueue(mq_name);
mq.ReceiveCompleted +=new ReceiveCompletedEventHandler(mq_ReceiveCompleted);
//定义消息到达时处理函数
string[] types = { "System.String" };
((XmlMessageFormatter)mq.Formatter).TargetTypeNames = types;
mq.BeginReceive();
解决方案示意图
<script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script> <script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>