Message Queuing(MSMQ)
一、前言
MicroSoft Message Queuing
(微软消息队列)是在多个不同的应用之间实现相互通信的一种异步传输模式
,相互通信的应用可以分布于同一台机器上,也可以分布于相连的网络空间中的任一位置。它的实现原理是:消息的发送者把自己想要发送的信息放入一个容器中(我们称之为Message),然后把它保存至一个系统公用空间的消息队列(Message Queue)
中;本地或者是异地的消息接收程序再从该队列中取出发给它的消息进行处理。
二、实质
在消息传递机制
中,有两个比较重要的概念。一个是消息
,一个是队列
。消息是由通信的双方所需要传递的信息,它可以是各式各样的媒体,如文本、声音、图象等等。消息最终的理解方式,为消息传递的双方事先商定,这样做的好处是,一是相当于对数据进行了简单的加密,二则采用自己定义的格式可以节省通信的传递量。消息可以含有发送和接收者的标识,这样只有指定的用户才能看到只传递给他的信息和返回是否操作成功的回执。消息也可以含有时间戳,以便于接收方对某些与时间相关的应用进行处理。消息还可以含有到期时间,它表明如果在指定时间内消息还未到达则作废,这主要应用与时间性关联较为紧密的应用。
消息队列是发送和接收消息的公用存储空间
,它可以存在于内存中
或者是物理文件中
。消息可以以两种方式发送,即快递方式(express)
和可恢复模式(recoverable)
,它们的区别在于,快递方式为了消息的快速传递,把消息放置于内存中,而不放于物理磁盘上,以获取较高的处理能力;可恢复模式在传送过程的每一步骤中,都把消息写入物理磁盘中,以得到较好的故障恢复能力。消息队列可以放置在发送方、接收方所在的机器上,也可以单独放置在另外一台机器上。正是由于消息队列在放置方式上的灵活性,形成了消息传送机制的可靠性。当保存消息队列的机器发生故障而重新启动以后,以可恢复模式发送的消息可以恢复到故障发生之前的状态,而以快递方式发送的消息则丢失了。另一方面,采用消息传递机制,发送方不必要再担心接收方是否启动、是否发生故障等等非必要因素,只要消息成功发送出去,就可以认为处理完成,而实际上对方可能甚至未曾开机,或者实际完成交易时可能已经是第二天了
三、作用
采用MSMQ带来的好处是:由于是异步通信
,无论是发送方还是接收方都不用等待对方返回成功消息,就可以执行余下的代码,因而大大地提高了事物处理的能力;当信息传送过程中,信息发送机制具有一定功能的故障恢复能力;MSMQ的消息传递机制使得消息通信的双方具有不同的物理平台成为可能。
在微软的.net平台上利用其提供的MSMQ功能,可以轻松创建或者删除消息队列、发送或者接收消息、甚至于对消息队列进行管理。
四、MSMQ API
在Net操作MSMQ 我们得使用MessageQueue
类(它在system.messaging.dll这个程序集中),通过它提供的API来管理MSMQ队列.
1.创建队列
创建队列,path代表队列的路径,transactional表示是否创建事务队列,默认为fasle。
public static MessageQueue Create(string path);
public static MessageQueue Create(string path, bool transactional);
2.验证队列
验证指定路径的队列是否存在,path代表队列的路径,表现形式为"主机名\队列名称"。
例如:".\private$\myQueue",其中".“代表本地主机,”\private$\myQueue"则代表队列的名称,"private$"表示我们创建的是专用队列,在网络上我们可以通过路径来唯一确定一个队列。
public static bool Exists(string path);
3.删除队列
删除队列,path代表队列的路径。
public static void Delete(string path);
4.发送消息
发送消息到MSMQ。obj代表我们的用户数据,transation表示将我们的发送操作纳入事务当中。
在前面我们说过MSMQ接收的是Message,但是在这里我们看到Send操作并未强制要求我们采用Message类型参数。这是因为当我传入一个Object参数数据时,在Send操作的内部自动的给我们创建了一个Message消息对象,并且将我们的传入的Object参数采用默认的序列化器序列化,然后装入Message的body属性当中,如果我们在Send方法中指定label属性,它将被赋值给Message的同名Label属性。当然我们完全可以自定义一个message对象传入Send方法中
public void Send(object obj);
public void Send(object obj, MessageQueueTransaction transaction);
public void Send(object obj, string label);
5.接受队列(Peek方式)
如果我们在接收消息的后,不想把MSMQ队列中的消息删除怎么办呢?那么采用下面的方法吧,因为这两个方法接收MSMQ的消息,不会删除MSMQ中对应的消息,所以他们不支持事务,即没有提供事务的参数。
public Message Peek();
如果我们想取指定标识的消息,就的采用如下的方法了,id代表消息的唯一标示
public Message PeekById(string id);
6.接受队列(Receive方式)
采用Receive方式在取MSMQ的消息时,如果成功,会把MSMQ的对应消息给删除掉,并且只能取到消息队里中的排队头的消息。
public Message Receive();
public Message Receive(MessageQueueTransaction transaction);
public Message Receive(TimeSpan timeout);
如果我们想取指定标识的消息,就的采用如下的方法了,id代表消息的唯一标示。
public Message ReceiveById(string id);
public Message ReceiveById(string id, MessageQueueTransaction transaction);
7.接受队列(接受全部)
我们可以使用GetAllMessages一次性把队列里面的所有消息取出来
public Message[] GetAllMessages();
五、MSMQ的安装
本次将使用win10系统自带的MSMQ进行演练,首先如果你使用的是Windows操作系统(不管是Windows Server、Windows Vista还是Windows 10,Windows 7,Windows 8等)都可以在无需下载的情况下安装微软提供MSMQ服务,相信很多微软用户对此比较熟悉。
1.开启MSMQ功能
打开 控制面板>程序>程序和功能>启动或关闭Windows功能
选择 MicroSoft Message Queue(MSMQ)服务器
点击确定等待安装完成
2.查看消息队列
打开 控制面板>系统和安全>管理工具>计算机管理
我们可以看到在服务和应用程序中有一个消息队列
,打开消息队列我们可以看到服务本身为我们提供了3中队列(传出队列、专用队列、系统队列)。
3.手动创建队列
在上面的三种队列中,用户能自由创建的只有专用队列,下面演示创建一个专用队列。
相关