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 plain copy print ? 在CODE上查看代碼片 派生到我的代碼片
  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.   
  13. namespace MsMQTest  
  14. {  
  15.     class Program  
  16.     {  
  17.         static void Main(string[] args)  
  18.         {  
  19.             //declare the MQ Path  
  20.             string ekQ= ".\\Private$\\EKTestQueue";  
  21.   
  22.             //create the MQ if the MQ is not exist  
  23.             if (!MessageQueue.Exists(ekQ))  
  24.                 MessageQueue.Create(ekQ);  
  25.   
  26.             //create a new queue  
  27.             var queue = new MessageQueue(ekQ);  
  28.   
  29.             for (int i = 0; i < 2; i++)  
  30.             {  
  31.                 //create the model that want to send  
  32.                 Test test=new Test();  
  33.                 test.Name = "fdsfd";  
  34.                 test.Sex = "cvx";  
  35.                 //serialize the model  
  36.                 string str = Program.xmlSerial(test);  
  37.                 //send the model data to queue  
  38.                 queue.Send("Test" + str);  
  39.                 Console.WriteLine("Message sent {0} \n--------------""Test" +str);  
  40.             }  
  41.   
  42.             Console.Read();  
  43.   
  44.             // MessageQueue.Delete(ekQ);  
  45.         }  
  46.   
  47.         public static string xmlSerial<T>(T serializeClass)  
  48.         {  
  49.             string xmlString = string.Empty;  
  50.             XmlWriterSettings settings = new XmlWriterSettings();  
  51.             XmlSerializer serializer = new XmlSerializer(typeof(T));  
  52.             StringBuilder xmlStringBuilder = new StringBuilder();  
  53.             using (XmlWriter writer = XmlWriter.Create(xmlStringBuilder))  
  54.             {  
  55.                 serializer.Serialize(writer, serializeClass);  
  56.                 xmlString = xmlStringBuilder.ToString();  
  57.             }  
  58.   
  59.             return xmlString;  
  60.         }  
  61.     }  
  62.   
  63.     public class Test  
  64.     {  
  65.         public string Name { getset; }  
  66.         public string Sex { getset; }  
  67.     }  
  68. }  

         對應的生成結果如下圖:


         運行上面的代碼后MQ將會把消息發送到相應的隊列中,這里采用的是專有隊列所以會將消息發送到本地的隊列中,查看消息如下圖所示:
  



          運行上面的代碼后會把消息發送到相應的消息隊列中,這樣在消息的發送方和調用方之間就構建了一個相互松耦合的橋梁,它就是消息隊列,接下來演示如何接收消息隊列。

[csharp] view plain copy print ? 在CODE上查看代碼片 派生到我的代碼片
  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.               
  15.             using (var queue = new MessageQueue(ekQ))  
  16.             {  
  17.                 queue.Formatter = new XmlMessageFormatter(new Type[] { typeof(String) });  
  18.                 var exist = false;  
  19.                 while (!MessageQueue.Exists(ekQ))  
  20.                 {  
  21.                     Console.WriteLine("No existing queue");  
  22.                           
  23.                 }  
  24.                 exist = true;  
  25.                 while (exist)  
  26.                 {  
  27.                     var m = queue.Receive();  
  28.                     Console.WriteLine("Message Received {0} \n--------------",(string)m.Body);  
  29.                     // Thread.Sleep(500);  
  30.                 }  
  31.             }  
  32.               
  33.         }  
  34.     }  
  35. }  

       運行程序后控制台輸出結果:




         在上例中我們使用的異步Receive方法,而且該方法會將消息隊列中的消息取出並刪除,所以在操作完成后消息隊列中的消息會為空,所以運行后的隊列為下圖:



結語


         MQ是一種企業服務的消息中間節技術,這種技術常常伴隨着企業服務總線相互使用,構成了企業分布式開發的一部分,如果考慮到消息的發送和傳送之間是可以相互不聯系的並且需要分布式架構,則可以考慮使用MQ做消息的中間價技術,MQ的功能已經足夠開發使用。但是對於分布式開發的技術只了解MQ是遠遠不足夠的,因為在系統中往往會實現消息的自動發送和獲取,如果想要實現消息隊列的自動操作就不得不說說Windows服務了,下文將會對Windows服務做詳細的討論。




版權聲明:本文為博主原創文章,未經博主允許不得轉載。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM