首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 與 MSMQ 訊息佇列開發完整指南:從入門到實戰

     編輯:關於C語言

前言

Microsoft Message Queuing (MSMQ) 是 Windows 內建的訊息中介軟體,支援異步、解耦、可靠傳遞的分散式通訊。雖然現代架構常用 RabbitMQ、Kafka、Azure Service Bus,但 MSMQ 在 Windows 生態內仍具備:零額外部署、事務支援、AD 整合、高可用等優勢。本文系統講解 C# 開發 MSMQ 應用的完整流程:安裝、佇列引用、發送/接收/閱讀訊息、序列化、錯誤處理。

1. 環境準備與安裝

  1. 安裝 MSMQ:控制台 → 程式集 → 開啟/關閉 Windows 功能 → Microsoft Message Queue (MSMQ) Server → 所有子項
  2. 工作群組 vs 網域:工作群組環境下公用佇列不可用,僅能用私有佇列;不影響開發測試
  3. 專案參考:右鍵專案 → 加入參考 → 組件 → 搜尋 System.Messaging → 勾選

2. 佇列路徑與引用

佇列類型路徑格式範例
公用佇列MachineName\QueueNameSERVER01\OrderQueue
私有佇列MachineName\Private$\QueueName.\Private$\OrderQueue
日誌佇列MachineName\QueueName\Journal$.\OrderQueue\Journal$

. 代表本機。兩種引用方式:


// 方式一:建構子指定路徑(佇列必須存在,否則拋出例外)
MessageQueue mq = new MessageQueue(@".\Private$\MyQueue");

// 方式二:屬性設定(可先建立佇列)
MessageQueue mq = new MessageQueue();
mq.Path = @".\Private$\MyQueue";

// 程式化建立佇列(若不存在)
if (!MessageQueue.Exists(@".\Private$\MyQueue")) {
    MessageQueue.Create(@".\Private$\MyQueue", transactional: true); // 交易型佇列
}

3. 發送訊息

3.1 簡單類型


mq.Send(1000);                    // 整數
mq.Send("Hello MSMQ!");           // 字串
mq.Send(DateTime.Now);            // 日期時間

3.2 複雜物件與訊息屬性控制


// 自定義類別(需可序列化)
[Serializable]
public class Order {
    public int OrderId { get; set; }
    public string Customer { get; set; }
    public decimal Amount { get; set; }
}

// 發送物件實例
Order order = new Order { OrderId = 1001, Customer = "Acme Corp", Amount = 999.99m };
mq.Send(order);  // 預設 XML 序列化

// 使用 Message 物件控制標籤、優先級、回應佇列等
Message msg = new Message(order);
msg.Label = "NewOrder";
msg.Priority = MessagePriority.High;
msg.ResponseQueue = responseQueue;  // 要求回覆
mq.Send(msg);

4. 接收與閱讀訊息

方法行為適用場景
Receive()阻塞等待、取出並移除訊息一般消費者
Receive(TimeSpan)超時可控制的阻塞接收輪詢、定時處理
Peek()讀取但不移除訊息監控、審計、預覽
ReceiveById(id) / PeekById(id)依訊息 ID 精確存取重試、去重

// 同步接收(含超時)
Message msg = mq.Receive(new TimeSpan(0, 0, 30)); // 30 秒超時

// 非同步接收(事件驅動)
mq.ReceiveCompleted += (sender, e) => {
    MessageQueue q = (MessageQueue)sender;
    Message m = q.EndReceive(e.AsyncResult);
    ProcessMessage(m);
    q.BeginReceive(); // 繼續監聽
};
mq.BeginReceive(); // 啟動非同步接收循環

5. 訊息反序列化:Formatter 關鍵設定

預設 XmlMessageFormatter 需明確指定目標類型,否則反序列化失敗:


// 設定可接受的類型陣列
string[] types = { "System.String", "MyNamespace.Order, MyAssembly" };
mq.Formatter = new XmlMessageFormatter(types);

// 接收並讀取 Body
Message msg = mq.Receive();
Order order = (Order)msg.Body;  // 自動反序列化
Console.WriteLine($"Order {order.OrderId}: {order.Customer} - {order.Amount}");

三大 Formatter 比較:

  • XmlMessageFormatter:預設、人類可讀、跨語言、效能中等
  • BinaryMessageFormatter:二進位、效能高、.NET 專用、版本敏感
  • ActiveXMessageFormatter:相容舊 COM/VB6 應用

6. 進階主題

6.1 交易式佇列(確保 exactly-once)


// 建立交易型佇列
MessageQueue.Create(@".\Private$\TxQueue", true);

// 發送端
using (MessageQueueTransaction tx = new MessageQueueTransaction()) {
    tx.Begin();
    mq.Send(order, tx);
    // 可包含資料庫操作等
    tx.Commit(); // 或 tx.Abort()
}

// 接收端
using (MessageQueueTransaction tx = new MessageQueueTransaction()) {
    tx.Begin();
    Message msg = mq.Receive(tx);
    Process((Order)msg.Body);
    tx.Commit(); // 處理失敗可 Abort,訊息回佇列
}

6.2 死信佇列與毒藥訊息處理

  • 訊息超時(TimeToReachQueue、TimeToBeReceived)或投遞失敗 → 進入死信佇列(系統/交易死信佇列)
  • 接收端連續失敗超過重試次數 → 訊息成為毒藥訊息,可移至子佇列人工處理

6.3 安全性與權限


// 設定佇列 ACL
MessageQueue mq = new MessageQueue(@".\Private$\SecureQueue");
mq.SetPermissions("DOMAIN\Users", MessageQueueAccessRights.SendMessage, AccessControlEntryType.Allow);
mq.SetPermissions("DOMAIN\Admins", MessageQueueAccessRights.FullControl, AccessControlEntryType.Allow);

7. 關閉資源與最佳實踐


mq.Close();  // 釋放非受控資源
mq.Dispose(); // 或 using 區塊
  • 重用 MessageQueue 實例:建立成本高,應為長生命週期
  • 非同步優於同步輪詢:減少執行緒佔用
  • 明確設定 Formatter:避免執行階段驚喜
  • 監控佇列深度:mq.GetAllMessages().Length 或 WMI/效能計數器
  • 大訊息分塊:MSMQ 單訊息預設 4MB 上限,大數據請外部存儲(檔案/資料庫/Blob)傳引用

總結

MSMQ 提供了 Windows 原生、企業級的訊息佇列能力。掌握 System.Messaging 命名空間的核心類別(MessageQueue、Message、MessageQueueTransaction、Formatter)、佇列路徑命名規則、同步/非同步接收模式、交易語義、序列化設定,即可構建健壯的分散式 C# 應用。雖然雲原生時代新選項眾多,但 MSMQ 在混合雲、遷移期、純 Windows 環境下仍是極具性價比的選擇。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved