MSMQ消息隊列 用法

引言

 

        接下來的三篇文章是討論有關企業分佈式開發的文章,這三篇文章籌劃了很長時間,文章的技術並不算新,可是文章中使用到的技術都是通過筆者研究實踐後總結的,正所謂站在巨人的肩膀上,筆者並非巨人,但也但願這幾篇文章可以幫助初涉企業分佈式開發的一些童鞋。
        三篇文章將會從MessageQueue、Windows Services和WCF着手來討論企業分佈式的開發,MQ是一種消息中間件技術,該篇文章將會詳細討論。Windows Services在分佈式開發中一樣起着重要的做用,將會在下篇文章中詳細討論,最後是使用MQ、WS並結合WCF作一個分佈式的Demo來演示分佈式的架構。在敲定寫這幾篇文章前還有一個重要的內容--ESB(Enterprise Service Bus,企業服務總線),它是傳統中間件技術與XML、Web服務等技術結合的產物,也就是集合了MQ和WS爲一體的一種框架,但尚未作詳細的研究因此這三篇文章就沒有包括ESB,等到有充足的時間了而後再去詳細的研究吧。
        

1、 論新技術的學習

 

         在使用到新技術時每每首先須要學習它,而後在項目中應用,這裏說到了學習那麼就來討論下技術學習的方法,也是筆者對新技術學習的一種總結。
         對於作舊了開發的人員來講在學習新技術時每每會比年輕的開發人員較快,這個問題有沒有想過?其實這個問題的答案至關的簡單,在學習新技術時對於不一樣的人都是站在同一個起跑線的,只不過對於有經驗的開發人員來講,在使用新技術時學習的並非它是什麼東西,而是學習的如何使用它。這種不一樣的思想觀點就決定了誰會掌握的更快,能夠這麼理解,開發是一個世界,剛踏入編程界的人來講就像是剛出生的一個嬰兒,這時候他們是要去認知這個世界,因而就會問不少問題,諸如:面向對象是什麼東西,爲何要這樣編寫,最後把本身陷入到一個個泥潭中。可是對於經驗豐富的開發人員來講,他要認知不是這個世界,在開發中能夠說已是成年人,在學習新技術時就不會問很愚蠢的問題,而是會想這個東西也是面向對象的,那麼能夠把方法封裝到一個基類中,子類繼承父類的方法,而後重寫來實現多態,因此這時候經驗就決定了學習新技術時的快慢。
         這就相似於生活中的幼兒和成年人在學習開電動車時的場景,想要幼兒使用電動車就會很困難,由於最簡單的腳踏車都沒有騎過,你讓他學習電動車,這不是做死的節奏嗎。可是成年人就不一樣了,成年人騎腳踏車至關的熟練,在換電動車的時候就會想這個和腳踏車是同樣的,並且能夠不用每次腳踩,真是好用。這兩種思惟方式就決定了幼兒在使用電動車時須要幾天的事件才能學會,可是成年人剛看到就可以使用。
          學習新技術也是相似,新技術也是隻是一種新的實現方式,可能給它加上了一個電動的開關,作一個開關而後使用它裏面的功能自個兒運行就能夠了,實際的內容仍是沒有改變都是0和1的集合體。


2、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服務作詳細的討論。




版權聲明:本文爲博主原創文章,未經博主容許不得轉載。服務器

相關文章
相關標籤/搜索