. Net環境下消息隊列(MSMQ)對象的應用
關於消息對象(MSMQ)的一些基本概念可以從《消息隊列(Message Queue)簡介及其使用》查閱,這裏歸納在.Net 環境下應用消息隊列(MSMQ)開發的一些基本對象和方法。
隊列類型及其相應的路徑格式:
Public: [MachineName]/[QueueName]
Private: [MachineName]/Private$/[QueueName]
Journal: [MachineName]/[QueueName]/Journal$
Machine journal: [MachineName]/Journal$
Machine dead-letter: [MachineName]/DeadLetter$
Machine transactional dead-letter: [MachineName]/XactDeadLetter$
The first portion of the path indicates a computer or domain name or uses a period (.) to indicate the current computer.
1. 創建消息隊列
可以手動的方式通過Windows提供的工具創建,或者通過程序的方式創建:
if(MessageQueue.Exists(".//Private$//MSMQDemo"))
queue = new MessageQueue(".//Private$//MSMQDemo");
else
queue = MessageQueue.Create(".//Private$//MSMQDemo");
2. 發送消息
缺省情況下,消息序列化XML格式,也可設置爲MessageQueue對象的Formatter屬性爲BinaryMessageFormatter,以二進制格式序列化。
設置消息序列化格式:
if(rdoXMLFormatter.Checked)
queue.Formatter = new XmlMessageFormatter();
else
queue.Formatter = new BinaryMessageFormatter();
發送簡單的文本消息:
string strMessage = "Hello, I am Rickie.";
queue.Send(strMessage, "Simple text message");
消息隊列可以傳送簡單的文本消息,也可以傳送對象消息,但需要滿足如下條件:
(1)class必須有一個無參數的公共構造函數,.Net使用這個構造函數在接收端重建對象。
(2)class必須標示爲serializable(序列化)。
(3)所有的class屬性必須可讀寫,因爲.Net在重建對象時不能夠恢復只讀屬性的屬性值,因此只讀屬性不能夠序列化。
發送對象消息(CustomerInfo class需要滿足上述條件):
CustomerInfo theCustomer = new CustomerInfo("0001", "Rickie Lee", "[email protected]");
queue.Send(theCustomer, "Object message");
3. 讀/顯示消息
當消息接受後,消息將從隊列中刪除。可以通過使用MessageQueue.Peek方法來檢索消息隊列中的第一個消息的複製,保留消息在隊列中。不過,這樣只能獲取的相同的消息。更好的辦法是通過foreach來讀消息隊列中的消息,但不刪除隊列中的消息。
foreach(System.Messaging.Message message in queue)
{
txtResults.Text += message.Label + Environment.NewLine;
}
4. 接收消息
一般而言,可以通過Receive方法來讀取隊列中的消息,對於非事務性的隊列,優先讀取高優先級的消息。如果隊列中有多個相同優先級的消息,則以先進先去的方式進行讀取消息。對於事務性的隊列,則完全以先進先去的方式進行讀取消息,忽略消息的優先級。
System.Messaging.Message receivedMessage;
receivedMessage = queue.Receive(TimeSpan.FromSeconds(5));
上面採用同步調用,並且一直等到隊列中有可用消息或超時過期。
Demo界面(不在提供DEMO程序):
其他相關事項:
- 關於消息的加密、路由等等特性,需要有配置Active Directory的消息隊列服務器。
- 爲了避免存放消息隊列的計算機重新啓動而丟失消息,可以通過設置消息對象的Recoverable屬性爲true,在消息傳遞過程中將消息保存到磁盤上來保證消息的傳遞,默認爲false。
- 消息發送方和消息接收方需採用相同的序列化格式,如XML或Binary。
- 建議每一個消息隊列存放相同類型的消息對象,這樣可以省掉獲取消息對象後,進行類型判別的麻煩。
5.消息隊列在分佈式系統中的應用
消息隊列MSMQ和數據庫不一樣,消息隊列缺乏足夠的錯誤檢查能力,並且MSMQ由於需要束縛在windows平臺,這些是MSMQ的不足之處。另外,在Production環境中,需要編寫大量的代碼來進行錯誤檢測和響應。還有大量的死信隊列、響應隊列和日記隊列可能部分在企業不同的計算機上,使得跟蹤這些問題或進行診斷變得比較困難。
但是,MSMQ作爲組件內部連接比較有用。例如,你可以創建一個XML Web Services使用MSMQ來轉發對另一個Server端組件的請求,這種設計巧妙迴避了其他異步調用的方法,並且確保可擴展性和性能。
References:
1, Matthew MacDonald, Microsoft® .NET Distributed Applications: Integrating XML Web Services and .NET Remoting
2, Rickie, 消息隊列(Message Queue)簡介及其使用