﻿# Message Queuing (MSMQ) 學習心得分享

之前有個案子有用到 [Message Queuing (MSMQ)](http://msdn.microsoft.com/en-us/library/ms711472\(VS.85\).aspx) 技術，但國內似乎採用這種技術的人不多，網路上能找到的都以 MSDN / TechNet 與英文內容居多，不過 MSMQ 是從 NT 4.0 的時代就有的服務，到現在也都還一直是 Windows 內建服務的一部分，但我之前在使用時由於過於生疏，一度誤以為 MSMQ 是個不可靠的服務，後來才證明說 MSMQ 真的是穩定又有效的訊息佇列服務，以下是一些心得筆記。

**佇列主要分 2 種**

-   **系統佇列 (System Queues)**
    -   主要用來處理系統相關的訊息。
    -   包含的訊息是用來認可接收指定訊息佇列網路內所傳送的訊息。
-   **使用者佇列**
    -   使用者可用來建立訊息的佇列

**使用者可用來建立訊息的佇列又分 4 種類型**

-   **私用佇列 (Private Queues)**
    -   可以從遠端主機傳送訊息到本機的佇列，但私用佇列只能從本機讀取訊息！
    -   可以設定訊息存取的安全性與使用權限 ！
    -   私用佇列只能由知道佇列完整路徑名稱或標籤 (Label) 的應用程式存取。
-   系統管理佇列 (Administration queues)
    -   包含的訊息是用來認可接收指定訊息佇列網路內所傳送的訊息。
-   公用佇列 (Public Queues)
    -   會複寫到整個訊息佇列網路，所有由網路連接的站台都可存取它。
    -   一定要有 Active Directory (AD) 的架構下才能使用。
    -   參考資料：[公用及私人佇列](http://technet.microsoft.com/zh-tw/library/cc776346%28WS.10%29.aspx) ( [Public and private queues](http://technet.microsoft.com/en-us/library/cc776346\(WS.10\).aspx) )
-   回應佇列 (Response queues)
    -   包含的回應訊息會在目的應用程式接收訊息時傳回至傳送應用程式。

**訊息傳遞的方式**

透過 [Message Queuing COM Components](http://msdn.microsoft.com/en-us/library/ms704064\(VS.85\).aspx) 或  .NET 的 [System.Messaging 命名空間](http://msdn.microsoft.com/zh-tw/library/system.messaging.aspx) 傳送訊息都會先將訊息送入本機的 **傳出佇列**(**Outgoing Queues**) 然後才透過本機的 MSMQ 服務將訊息轉送到目的地，目的地可以是本機的 **私用佇列(Private Queues)** 或 遠端的 **私用佇列(Private Queues)** 或 **其他類型的使用者佇列**。

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/208e9dc7240716b26b36-image.png)

這觀念是我碰了好多[釘子](/post/2010/03/23/The-Devil-in-the-detail-about-loopback-IP-address)才知道的，要看訊息有沒有轉送到目的地只要點選如上圖 **傳出佇列**(**Outgoing Queues**) 的節點，然後看右側視窗是否有未完成的訊息要轉送，或傳遞過程中是否有留下的錯誤訊息。

**如何表達 MSMQ 傳送路徑**

這裡有篇簡單的文章說明如何利用 .NET 透過 MSMQ 傳送訊息

-   [MSMQ - Sending messages to remote private queues](https://web.archive.org/web/20210620064147/https://www.infosysblogs.com/microsoft/2007/02/msmq_sending_message_to_remote.html)

表達 MSMQ 傳送路徑有分兩種方式，表達的名稱稱為 FormatName，大致的[格式](http://msdn.microsoft.com/en-us/library/ms705703.aspx)如下：

-   PUBLIC=QueueGUID
-   DIRECT=Protocol:ComputerAddress\\QueueName
-   DIRECT=OS:ComputerName\\private$\\QueueName
-   PRIVATE=ComputerGUID\\QueueNumber

對於想要直接傳到訊息到目的地的寫法稱為 [Direct Format Names](http://msdn.microsoft.com/en-us/library/ms700996\(VS.85\).aspx)，大致格式如下：

-   DIRECT=AddressSpecification\\QueueName  (For public queues.)
-   DIRECT=AddressSpecification\\PRIVATE$\\QueueName  (For private queues.)
-   DIRECT=AddressSpecification\\SYSTEM$;computersystemqueue  (Introduced in MSMQ 2.0)
-   DIRECT=HTTP://URLAddressSpecification/msmq/QueueName  (Introduced in MSMQ 3.0)
-   DIRECT=HTTPS://URLAddressSpecification/msmq/QueueName  (Introduced in MSMQ 3.0)

**處理常見的 MSMQ 操作錯誤**

請參考這篇文章：[MessageQueueErrorCode Enumeration](http://msdn.microsoft.com/en-us/library/system.messaging.messagequeueerrorcode\(VS.80\).aspx)

**其他與安全相關的文章**

-   [MSMQ 3.0 too secure for you?](http://blogs.msdn.com/johnbreakwell/archive/2007/01/15/msmq-3-0-too-secure-for-you.aspx)
-   [Understand What Security Context to Use](http://msdn.microsoft.com/#msmqbest_security)
-   [Message Queuing security overview](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/msmq/ms705295\(v=vs.85\)).
-   [Programming Best Practices with Microsoft Message Queuing Services (MSMQ)](http://msdn.microsoft.com/en-us/library/ms811053.aspx)
    -   **Understand what security context to use**
        -   By default, all services run in the context of a local system. The local system is only a valid account on the computer hosting the service. With the default, MSMQ permissions will fail all receive operations to remote computers. Unfortunately, sends will work because the default for send access is "Everyone." The overhead inherent in attempting to validate an invalid user on the domain shows up as huge delays in sends reaching the destination queue. The classic symptom of this problem has sends immediately succeeding but leaving the sending computer in 30-second intervals (viewable in the performance monitor).
-   [MSMQ overhead when you use message security features](https://web.archive.org/web/20110228053323/http://support.microsoft.com:80/kb/256630)

**MSMQ 各版本與作業系統的對應**

-   MSMQ 1.0
    -   Microsoft® Windows NT® 4.0, Windows® 95, and Windows 98.
-   MSMQ 2.0
    -   Microsoft Windows 2000
-   MSMQ 3.0
    -   Microsoft Windows XP Professional and members of the Windows Server 2003 family.
    -   MSMQ is also available with independent client functionality on computers running Windows CE 3.0.
-   MSMQ 4.0
    -   Microsoft Windows Vista and members of the Windows Server 2008 family
-   MSMQ 5.0
    -   Microsoft Windows 7 and members of the Windows Server 2008 R2 family
    -   [MSMQ 5.0 - Changes introduced with Windows 7 and Windows Server 2008 R2](https://learn.microsoft.com/en-us/archive/blogs/johnbreakwell/msmq-5-0-changes-introduced-with-windows-7-and-windows-server-2008-r2)

**相關連結**

-   [Message Queuing (MSMQ)](http://msdn.microsoft.com/en-us/library/ms711472\(VS.85\).aspx)
-   [Message Queuing 訊息佇列](http://technet.microsoft.com/zh-tw/library/cc732184.aspx) ( TechNet - Windows Server 2008 R2 )
-   [Message Queuing 訊息佇列](http://technet.microsoft.com/zh-tw/library/cc757108%28WS.10%29.aspx) ( TechNet - Windows Server 2003 )
-   [訊息佇列和訊息技術背景資料](http://msdn.microsoft.com/zh-tw/library/19ww660c.aspx)
-   [Visual C# 概念 - 建立佇列](http://msdn.microsoft.com/zh-tw/library/cc438007%28VS.71%29.aspx)
-   [Message Queuing and Queued Components (MSMQ)](http://msdn.microsoft.com/en-us/library/ms878320.aspx)
-   [Microsoft Message Queuing - Wikipedia, the free encyclopedia](http://en.wikipedia.org/wiki/Microsoft_Message_Queuing)
-   [How To Optimize MSMQ Performance](http://support.microsoft.com/kb/199428/en-us)
-   [MSMQ for .NET Developers (Part 1)](https://web.archive.org/web/20211127171801/https://www.devx.com/dotnet/Article/27560/0/page/6)
-   MSMQ for .NET Developers, Part 2
-   [MSMQ, Your Reliable Asynchronous Message Processing](https://web.archive.org/web/20150907085902/http://www.csharphelp.com:80/2007/06/msmq-your-reliable-asynchronous-message-processing/)
-   [MessageQueue.BeginReceive 方法](http://msdn.microsoft.com/zh-tw/library/43h44x53.aspx)
-   [SOA'izing MSMQ with WCF (and Why It's Worth It)](https://web.archive.org/web/20110102000253/http://code.msdn.microsoft.com:80/msmqpluswcf)
-   [MessageQueue 類別](http://msdn.microsoft.com/zh-tw/library/system.messaging.messagequeue.aspx) ( 有範例程式 )
-   [MSMQ, WCF and IIS: Getting them to play nice - Part 2](http://dotnet.dzone.com/news/msmq-wcf-and-iis-getting-them--0)
-   [佇列通訊的最佳做法](http://msdn.microsoft.com/zh-tw/library/ms731093.aspx)
-   [有害訊息處理](http://msdn.microsoft.com/zh-tw/library/ms789028.aspx)
-   [Windows Communication Foundation 中的佇列](http://msdn.microsoft.com/zh-tw/library/ms731089.aspx)
