MSMQ消息队列 用法

引言

接下来的三篇文章是讨论有关企业分布式开发的文章,这三篇文章筹划了很长时间,文章的技术并不算新,但是文章中使用到的技术都是经过笔者研究实践后总结的,正所谓站在巨人的肩膀上,笔者并不是巨人,但也希望这几篇文章能够帮助初涉企业分布式开发的一些童鞋。
        三篇文章将会从MessageQueue、Windows Services和WCF着手来讨论企业分布式的开发,MQ是一种消息中间件技术,该篇文章将会详细讨论。Windows Services在分布式开发中同样起着重要的作用,将会在下篇文章中详细讨论,最后是使用MQ、WS并结合WCF做一个分布式的Demo来演示分布式的架构。在敲定写这几篇文章前还有一个重要的内容--ESB(Enterprise Service Bus,企业服务总线),它是传统中间件技术与XML、Web服务等技术结合的产物,也就是集合了MQ和WS为一体的一种框架,但还没有做详细的研究所以这三篇文章就没有包括ESB,等到有充足的时间了然后再去详细的研究吧。

一、 论新技术的学习

在使用到新技术时往往首先需要学习它,然后在项目中应用,这里说到了学习那么就来讨论下技术学习的方法,也是笔者对新技术学习的一种总结。
         对于做旧了开发的人员来说在学习新技术时往往会比年轻的开发人员较快,这个问题有没有想过?其实这个问题的答案相当的简单,在学习新技术时对于不同的人都是站在同一个起跑线的,只不过对于有经验的开发人员来说,在使用新技术时学习的并不是它是什么东西,而是学习的如何使用它。这种不同的思想观点就决定了谁会掌握的更快,可以这么理解,开发是一个世界,刚踏入编程界的人来说就像是刚出生的一个婴儿,这时候他们是要去认知这个世界,于是就会问很多问题,诸如:面向对象是什么东西,为什么要这样编写,最后把自己陷入到一个个泥潭中。但是对于经验丰富的开发人员来说,他要认知不是这个世界,在开发中可以说已经是成年人,在学习新技术时就不会问很愚蠢的问题,而是会想这个东西也是面向对象的,那么可以把方法封装到一个基类中,子类继承父类的方法,然后重写来实现多态,所以这时候经验就决定了学习新技术时的快慢。
         这就类似于生活中的幼儿和成年人在学习开电动车时的场景,想要幼儿使用电动车就会很困难,因为最简单的脚踏车都没有骑过,你让他学习电动车,这不是作死的节奏吗。但是成年人就不同了,成年人骑脚踏车相当的熟练,在换电动车的时候就会想这个和脚踏车是一样的,而且可以不用每次脚踩,真是好用。这两种思维方式就决定了幼儿在使用电动车时需要几天的事件才能学会,但是成年人刚看到就能够使用。
          学习新技术也是类似,新技术也是只是一种新的实现方式,可能给它加上了一个电动的开关,做一个开关然后使用它里面的功能自个儿运行就可以了,实际的内容还是没有改变都是0和1的集合体。

二、MQ

上文讨论了学习的方法,接下来将会进入文章的正题,讨论有关MQ的基本使用方法。首先来对MQ的基本内容进行分类,这里从静态和行为角度将MQ的内容分为两大类,其中的静态角度是指MQ所包含的类别以及在系统消息队列中的类型,行为角度是指MQ在通信方面的类型,具体分类如下图:

        MQ是一种通信的机制,因为是一种中间件技术,所以它能够支持多种类型的语言开发,同时也是跨平台的通信机制,也就是说MQ支持将信息转化为XML或者JSon等类型的数据存储到消息队列中,然后可以使用不同的语言来处理消息队列中的消息,这样就很容易的做到了信息的通信,同时也为信息的通信起到了缓冲的作用,经常会在金融项目中使用这种通信机制。

2.1 理论积淀

2.1.1 静态

消息队列是和网络相关联的,所以根据网络的不同划分为公共队列、专用队列,其中公共队列是公布到整个网络中,在整个网络中所有站点公开,相对的就是专用队列,专用队列只能由知道队列完整路径名或标签的应用程序访问。另外根据接收消息的操作不同把消息队列划分为管理队列和响应队列,管理队列是指在整个消息线路中所有已经发送和接收的消息;响应队列是指目标程序接收和回应消息。它们在消息队列中的类型,可以使用下图来进行区分。

另外对于系统生成的队列这里不再详细的描述,可以上网查看一些文章。

2.1.2 行为

在行为方面从队列的通信和消息处理两个大的方面把MQ分为两大类,其中MQ的队列通信分为同步和异步两种类型,同步消息是指请求的发送方执行其他任务前,必须等待来自预定接收方的响应,具体等待的时间取决于接收方处理响应的时间。和同步相对应的是异步消息,发送方不会等待接收方的任何回应即可继续其它的操作。

另外在消息队列交互方面,消息的交互同时也有数据完整性、数据一致性、稳定性等类型的,具体分为稳定性、消息优先级、脱机能力、事务性和安全性等。

2.2 MQ 详解

理论部分已经积累的很多了,接下来我们从实际的代码实例中来分析MQ的使用方法,另外在使用MQ前首先应该要安装MQ才可以,这样在本机的服务器上才会有MQ的管理器,做消息处理的时候可以查看消息的具体内容。

2.2.1 MQ安装

打开Control Panel-“Add/Remove Programs” – “Add/Remove Windows Components”步骤安装MSMQ。

MSMQ可以安装为工作组模式或域模式。如果安装程序没有找到一台运行提供目录服务的消息队列的服务器,则只可以安装为工作组模式,此计算机上的“消息队列”只支持创建专用队列和创建与其他运行“消息队列”的计算机的直接连接。

2.2.2 配置MSMQ

打开Computer Management – Message Queuing,在Private Queues下创建MSMQDemo队列

2.2.3 MQ Demo

在.NET中微软对MQ做了封装,把MQ有关的信息封装到了MessageQueue类中,在开发的时候可以直接引用该类,对队列中的消息做操作。
        在操作消息前首先要为消息指定存储的队列,所以在创建消息时首先要在服务器上创建一个队列,然后为MessageQueue指定消息队列的路径。具体MQ类的方法和属性如下导图:

MQ类的主要使用方法已经在上面的导图中列出,接下来分析类中的主要方法和属性。
        (1)在Method中分为队列管理和消息管理两类方法,其中的队列管理的方法很简单,通过调用方法就能够创建和删除队列。另外就是消息管理的方法,其中的方法分为同步和异步两种类型,可以根据实际的需求来确定使用的类型。
        (2)在Property中主要用到的主要是Path和Label属性,其中的Path指定消息的队列地址,Label能设置或获取队列描述信息。

接下来演示发送数据和接收数据代码的编写方法,下面的示例中使用的是私有的队列类型来演示的操作。首先从发送数据开始,在发送数据时首先要创建我们的MQ,然后根据MQ的地址创建相应的队列,调用队列的send方法将数据信息发送到队列中,如下代码:

[csharp] view plaincopyprint?

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using System.Messaging;
  6. using System.Runtime.CompilerServices;
  7. using System.Text;
  8. using System.Threading;
  9. using System.Xml;
  10. using System.Xml.Serialization;
  11. using System.Runtime.Serialization.Formatters.Binary;
  12. namespace MsMQTest
  13. {
  14. class Program
  15. {
  16. static void Main(string[] args)
  17. {
  18. //declare the MQ Path
  19. string ekQ= ".\\Private$\\EKTestQueue";
  20. //create the MQ if the MQ is not exist
  21. if (!MessageQueue.Exists(ekQ))
  22. MessageQueue.Create(ekQ);
  23. //create a new queue
  24. var queue = new MessageQueue(ekQ);
  25. for (int i = 0; i < 2; i++)
  26. {
  27. //create the model that want to send
  28. Test test=new Test();
  29. test.Name = "fdsfd";
  30. test.Sex = "cvx";
  31. //serialize the model
  32. string str = Program.xmlSerial(test);
  33. //send the model data to queue
  34. queue.Send("Test" + str);
  35. Console.WriteLine("Message sent {0} \n--------------", "Test" +str);
  36. }
  37. Console.Read();
  38. // MessageQueue.Delete(ekQ);
  39. }
  40. public static string xmlSerial<T>(T serializeClass)
  41. {
  42. string xmlString = string.Empty;
  43. XmlWriterSettings settings = new XmlWriterSettings();
  44. XmlSerializer serializer = new XmlSerializer(typeof(T));
  45. StringBuilder xmlStringBuilder = new StringBuilder();
  46. using (XmlWriter writer = XmlWriter.Create(xmlStringBuilder))
  47. {
  48. serializer.Serialize(writer, serializeClass);
  49. xmlString = xmlStringBuilder.ToString();
  50. }
  51. return xmlString;
  52. }
  53. }
  54. public class Test
  55. {
  56. public string Name { get; set; }
  57. public string Sex { get; set; }
  58. }
  59. }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Messaging;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Xml;
using System.Xml.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace MsMQTest
{
    class Program
    {
        static void Main(string[] args)
        {
            //declare the MQ Path
            string ekQ= ".\\Private$\\EKTestQueue";

            //create the MQ if the MQ is not exist
            if (!MessageQueue.Exists(ekQ))
                MessageQueue.Create(ekQ);

            //create a new queue
            var queue = new MessageQueue(ekQ);

            for (int i = 0; i < 2; i++)
            {
                //create the model that want to send
                Test test=new Test();
                test.Name = "fdsfd";
                test.Sex = "cvx";
                //serialize the model
                string str = Program.xmlSerial(test);
                //send the model data to queue
                queue.Send("Test" + str);
                Console.WriteLine("Message sent {0} \n--------------", "Test" +str);
            }

            Console.Read();

            // MessageQueue.Delete(ekQ);
        }

        public static string xmlSerial<T>(T serializeClass)
        {
            string xmlString = string.Empty;
            XmlWriterSettings settings = new XmlWriterSettings();
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            StringBuilder xmlStringBuilder = new StringBuilder();
            using (XmlWriter writer = XmlWriter.Create(xmlStringBuilder))
            {
                serializer.Serialize(writer, serializeClass);
                xmlString = xmlStringBuilder.ToString();
            }

            return xmlString;
        }
    }

    public class Test
    {
        public string Name { get; set; }
        public string Sex { get; set; }
    }
}

对应的生成结果如下图:

运行上面的代码后MQ将会把消息发送到相应的队列中,这里采用的是专有队列所以会将消息发送到本地的队列中,查看消息如下图所示:

运行上面的代码后会把消息发送到相应的消息队列中,这样在消息的发送方和调用方之间就构建了一个相互松耦合的桥梁,它就是消息队列,接下来演示如何接收消息队列。

[csharp] view plaincopyprint?

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Messaging;
  5. using System.Text;
  6. using System.Threading;
  7. namespace MsqueueReaderTest
  8. {
  9. class Program
  10. {
  11. static void Main(string[] args)
  12. {
  13. string ekQ = ".\\Private$\\EKTestQueue";
  14. using (var queue = new MessageQueue(ekQ))
  15. {
  16. queue.Formatter = new XmlMessageFormatter(new Type[] { typeof(String) });
  17. var exist = false;
  18. while (!MessageQueue.Exists(ekQ))
  19. {
  20. Console.WriteLine("No existing queue");
  21. }
  22. exist = true;
  23. while (exist)
  24. {
  25. var m = queue.Receive();
  26. Console.WriteLine("Message Received {0} \n--------------",(string)m.Body);
  27. // Thread.Sleep(500);
  28. }
  29. }
  30. }
  31. }
  32. }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Messaging;
using System.Text;
using System.Threading;
namespace MsqueueReaderTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string ekQ = ".\\Private$\\EKTestQueue";

            using (var queue = new MessageQueue(ekQ))
            {
                queue.Formatter = new XmlMessageFormatter(new Type[] { typeof(String) });
                var exist = false;
                while (!MessageQueue.Exists(ekQ))
                {
                    Console.WriteLine("No existing queue");

                }
                exist = true;
                while (exist)
                {
                    var m = queue.Receive();
                    Console.WriteLine("Message Received {0} \n--------------",(string)m.Body);
                    // Thread.Sleep(500);
                }
            }

        }
    }
}

运行程序后控制台输出结果:

在上例中我们使用的异步Receive方法,而且该方法会将消息队列中的消息取出并删除,所以在操作完成后消息队列中的消息会为空,所以运行后的队列为下图:

结语

MQ是一种企业服务的消息中间节技术,这种技术常常伴随着企业服务总线相互使用,构成了企业分布式开发的一部分,如果考虑到消息的发送和传送之间是可以相互不联系的并且需要分布式架构,则可以考虑使用MQ做消息的中间价技术,MQ的功能已经足够开发使用。但是对于分布式开发的技术只了解MQ是远远不足够的,因为在系统中往往会实现消息的自动发送和获取,如果想要实现消息队列的自动操作就不得不说说Windows服务了,下文将会对Windows服务做详细的讨论。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-17 04:43:50

MSMQ消息队列 用法的相关文章

【转】MSMQ消息队列安装

一.Windows 7安装.管理消息队列1.安装消息队列   执行用户必须要有本地 Administrators 组中的成员身份,或等效身份.   具体步骤:    开始—>控制面板—>程序—>程序和功能—>打开或关闭Windows功能—>依次展开Microsoft Message Queue (MSMQ) 服务器.Microsoft Message Queue (MSMQ) 服务器核心—>确定   如果系统提示您重新启动计算机,请单击“确定”以完成安装.2.管理消息队

(转)MSMQ(消息队列)

原文作者:虔诚者    点此传送至原文 前段时间研究WCF接触到了MSMQ,所以认真的学习了一下,下面是我的笔记. 我理解的MSMQ MSMQ可以被看成一个数据储存装置,就如同数据库,只不过数据存储的是一条一条的记录,而MSMQ存储的是一个一个的消息(messsge).Message可以被理解为一种数据容器,我们在稍后会讲到.MSMQ一个重要的应用场景就是离线信息交互,例如,我们在给朋友发送邮件,而此时朋友并未登入邮箱,这个时候我们的邮件就可以发到邮件服务器的MSMQ队列中,当朋友登入邮箱的时候

微软MSMQ消息队列的使用

首先在windows系统中安装MSMQ 一.MSMQ交互 开发基于消息的应用程序从队列开始.MSMQ包含四种队列类型: 外发队列:消息发送到目的地之前,用它来临时存储消息. 公共队列:在主动目录中公布.整个网络各种服务器上的应用程序能够通过主动目录找到并应用公共队列. 私有队列:这些是本地服务器上的队列,对其它服务器无效(因此这些队列不在主动目录中公布.) 系统队列:包含日记队列(由系统生成).死队列和事务型死信队列.死消息无法传送. System.Messaging命名空间执行MSMQ的编程操

WCF分布式开发必备知识(1):MSMQ消息队列

本章我们来了解下MSMQ的基本概念和开发过程.MSMQ全称MicroSoft Message Queue,微软消息队列,是在多个不同应用之间实现相互通信的一种异步传输模式,相互通信的应用可以分布于同一台机器上,也可以分布于相连的网络空间的任一位置.它的实现原理是:消息的发送者要把自己想要发送的信息放入一个容器中(我们称之为Message),然后把它保存至一个系统公用空间的消息队列(Message Queue)中,本地或者是异地的消息接收程序再从该队列中取出发给它的消息进行处理.其中两个重要的概念

MSMQ(消息队列)续

在上一篇我简单介绍了MSMQ的相关概念,本篇将以代码说明 Message Message是MSMQ的数据存储单元,我们的用户数据一般也被填充在Message的body当中,因此很重要,让我们来看一看其在.net中的体现,如图: 在图上我们可以看见,Message提供了三个构造函数,参数body表示我们的用户数据,当我们在构造函数中传入,数据最终会被赋值给其同名属性body,参数formatter对应同名属性Formatter,它是一个序列化器,当我们的用户数据是一个复杂类型,比如类的时候Mess

MSMQ(消息队列)

前段时间研究WCF接触到了MSMQ,所以认真的学习了一下,下面是我的笔记. 我理解的MSMQ MSMQ可以被看成一个数据储存装置,就如同数据库,只不过数据存储的是一条一条的记录,而MSMQ存储的是一个一个的消息(messsge).Message可以被理解为一种数据容器,我们在稍后会讲到.MSMQ一个重要的应用场景就是离线信息交互,例如,我们在给朋友发送邮件,而此时朋友并未登入邮箱,这个时候我们的邮件就可以发到邮件服务器的MSMQ队列中,当朋友登入邮箱的时候,系统在从服务器的MSMQ队列中取出U件

MSMQ消息队列

一.引言 Windows Communication Foundation(WCF)是Microsoft为构建面向服务的应用程序而提供的统一编程模型,该服务模型提供了支持松散耦合和版本管理的序列化功能,并提供了与消息队列(MSMQ).COM+.Asp.net Web服务..NET Remoting等微软现有的分布式系统技术.利用WCF平台,开发人员可以很方便地构建面向服务的应用程序(SOA).可以认为,WCF是对之前现有的分布式技术(指的是MSMQ..NET Remoting和Web 服务等技术

跟我一起学WCF(1)——MSMQ消息队列

一.引言 Windows Communication Foundation(WCF)是Microsoft为构建面向服务的应用程序而提供的统一编程模型,该服务模型提供了支持松散耦合和版本管理的序列化功能,并提供了与消息队列(MSMQ).COM+.Asp.net Web服务..NET Remoting等微软现有的分布式系统技术.利用WCF平台,开发人员可以很方便地构建面向服务的应用程序(SOA).可以认为,WCF是对之前现有的分布式技术(指的是MSMQ..NET Remoting和Web 服务等技术

MSMQ消息队列总结

1.总体介绍: http://www.cnblogs.com/beniao/archive/2008/06/26/1229934.html 2.windows服务各项参数介绍及安装 https://www.cnblogs.com/xujie/p/5695673.html 3.遇到的问题 3.1.网络中传输信息 应该使用Json/XML格式传输: 3.2.GetAllMessages()方法:得到队列中的所有消息,但是未移除消息: 3.3.权限不足 3.3.1.本机(win7)配置  消息队列给e