之前曾經寫過一個關於MSMQ消息隊列的文章:WCF分布式開發必備知識 (1):MSMQ消息隊列 ,當時的目的也是用它來作為學習WCF 消息隊列MSMQ編程的 基礎文章。在那篇文章裡,我們詳細介紹了MSMQ消息隊列的基本概念、安裝、部 署、開發、調試等相關問題。今天我們來學習WCF分布式開發步步為贏(13):WCF 服務離線操作與消息隊列MSMQ。在WCF框架下使用MSMQ消息隊列服務編程。 這 裡我會給出一個使用WCF MSMQ實現離線請求的DEMO示例程序。
全文結構是:【1】MSMQ基本概念【2】WCF消息隊列MSMQ的優勢【3】WCF 消 息隊列MSMQ通信框架【4】安裝配置注意事項【5】示例代碼 【總結】
【1】MSMQ基本概念:
簡要回顧一下MSMQ的基本概念,詳細的你們可以參考WCF分布式開發必備知識 (1):MSMQ消息隊列。
MSMQ全稱MicroSoft Message Queue,微軟消息隊列,是在多個不同的應用之 間實現相互通信的一種異步傳輸模式,相互通信的應用可以分布於同一台機器上 ,也可以分布於相連的網絡空間中的任一位置。它的實現原理是:消息的發送者 把自己想要發送的信息放入一個容器中(我們稱之為Message),然後把它保存 至一個系統公用空間的消息隊列(Message Queue)中;本地或者是異地的消息接 收程序再從該隊列中取出發給它的消息進行處理。
【2】WCF消息隊列MSMQ的優勢:
消息隊列MSMQ的優點:穩定、消息優先級、脫機能力以及安全性,有保障的消 息傳遞和執行許多業務處理的可靠的防故障機制。 因此消息隊列是實現SOA面向 服務架構的重要組件之一。WCF框架提供了和MSMQ集成與擴展的能力。這一點也 是WCF在特性中明確指出的。MSMQ支持離線消息模式,而且在WCF框架下,提供了 基於http橋的internet網絡隊列服務的調用擴展。和MSMQ框架的結合和擴展,使 得WCF服務具有的新的特點:
【2.1】Availabiliy:可用性。這個是MSMQ離線消息的一種體現。客戶單和服 務端不需要實時進行連接,然後進行消息的交互.WCF 客戶端可以發送請求到離 線服務端,服務上線以後在相應客戶端請求。
【2.2】Disjoint:分解。可以講工作分解為多個操作,一次放入隊列。改善 系統的可用性和吞吐量。
【2.3】Compensating:補償。對於多業務事務,可以提供單獨的事物提供其 它事務失敗的善後處理。
【2.4】Load Leveling:負載平衡。可以把過載的客戶端請求放入隊列,空閒 的時候進行處理,平衡系統的吞吐量,改善性能。
【3】WCF 消息隊列MSMQ通信框架:
WCF使用NetMsmqBinding來支持消息隊列通信。當客戶端調用服務時,客戶端 消息會被封裝為MSMQ消息,發送懂到特定的消息隊列。服務端宿主在運行轉台下 會,啟動通道偵聽器,來檢測消息隊列消息,如果發現對應的消息,會從隊列裡 取出消息,使用分發器轉發給對應的服務。具體的通信架構如圖:
如果宿主離線,消息會被放入隊列,等待下一次宿主聯機時,在執行消息分 發處理,給指定的WCF服務。
【4】安裝配置注意事項:
MSMQ隊列幾種常見的類型就是:
1.公共隊列:在整個消息隊列網絡中復制,並且有可能由網絡連接的所有站 點訪問。
2.專用隊列:不在整個網絡中發布。相反,它們僅在所駐留的本地計算機上可 用。專用隊列只能由知道隊列的完整路徑名或標簽的應用程序訪問。
3.管理隊列:包含確認在給定“消息隊列”網絡中發送的消息回執的消息。指 定希望 MessageQueue 組件使用的管理隊列(如果有的話)。
4.響應隊列:包含目標應用程序接收到消息時返回給發送應用程序的響應消 息。指定希望 MessageQueue 組件使用的響應隊列(如果有的話)。
這裡有幾個問題要注意,以前很多人也在配置MSMQ開發環境的時候遇到這個 問題。Xp環境下作MSMQ配置開發有很多限制。這裡算是做個總結供大家參 考:
1.公共隊列需要域控制器DC Domain Controller;
2.私有隊列與托管的機器同屬本地,不需要DC,成為工作組安裝;
3.私有隊列需要禁用安全模式:工作組安裝與安全,安全設置需要客戶端提 供證書,MSMQ傳輸安全需要使用Windows安全,這裡需要使用AD活動目錄。
【5】示例代碼 :
今天的示例DEMO程序代碼,主要演示的是WCF如何配置和開發一個MSMQ服務程 序,實現WCF離線操作,MSMQ事務的部分由於內容較多,這裡暫時不涉及。我們 只討論WCF離線操作。
(1)WCF服務代碼:
值得注意的WCF的操作要被定義為單向操作,因為本質上其符合單向操作的特 征。異步,離線。無返回值。配置操作契約的時候要添加IsOneWay屬性。代碼如 下:
//1.服務契約
[ServiceContract(Namespace = "http://www.cnblogs.com/frank_xl/")]
public interface IWCFMSMQService
{
//操作契約,必須為單向操作
[OperationContract(IsOneWay = true)]
void SayHelloMSMQ(string name);
}
//2.服務類,繼承接口。實現服務契約定義的操作
public class WCFMSMQService : IWCFMSMQService
{
public WCFMSMQService()
{
Console.WriteLine("WCF MSMQ Service instance was created at:{0}", DateTime.Now);
}
//實現接口定義的方法
public void SayHelloMSMQ(string name)
{
Console.WriteLine("Hello! {0},Calling WCF MSMQ Service Operation at:{1}", name,DateTime.Now);
}
}
(2)宿主:
我的開發環境為XP專業版,工作組模式。這裡有個問題要注意,就是安全。 MSMQ默認的安全模式是需要證書支持。我們必須在宿主配置文件裡給配置為none ,簡化操作,因為證書需要MSMQ域管理器。MSMQ傳輸安全需要Windows安全,這個 又需要AD活動目錄支持,工作組模式下不支持,因此這裡我們都設置為none。代 碼如下:
<services>
<service behaviorConfiguration="WCFService.WCFServiceBehavior"
name="WCFService.WCFMSMQService">
<endpoint
address="net.msmq://localhost/Private/FrankWCFMSMQ"
binding="netMsmqBinding"
contract="WCFService.IWCFMSMQService" bindingConfiguration="msmq" >
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8001/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WCFService.WCFServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netMsmqBinding>
<binding name="msmq" durable="false" exactlyOnce="false">
<security mode="None">
<transport msmqProtectionLevel="None"/>
<message clientCredentialType="None"/>
</security>
</binding>
</netMsmqBinding>
</bindings>
(3)客戶端:
運行客戶端,添加服務引用,這裡客戶端的配置文件要做修改,安全模式也 修改和宿主對應,設置為none。客戶端測試方案是每個2秒調用一次服務請求。 我們這裡在宿主端打印了時間。客戶端發送消息完畢以後,宿主暫時不啟動。等 待一段時間。在啟動宿主,觀察宿主打印的消息。代碼如下:
//HTTP NetMsmqBinding_IWCFMSMQService
WCFMSMQServiceClient wcfServiceProxy = new WCFMSMQServiceClient("NetMsmqBinding_IWCFMSMQService");
//通過代理調用SayHello服務,這裡及時服務調用服務失敗,消息會發送到隊 列裡進行緩存。
Console.WriteLine("WCF First Call at:{0}",DateTime.Now);
wcfServiceProxy.SayHelloMSMQ("Frank");
Thread.Sleep(2000);//客戶端休眠兩秒,繼續下一次調用
Console.WriteLine("WCF Second Call at:{0}", DateTime.Now);
wcfServiceProxy.SayHelloMSMQ("Frank Xu");
Thread.Sleep(2000);//客戶端休眠兩秒,繼續下一次調用
Console.WriteLine("WCF Last Call at:{0}", DateTime.Now);
wcfServiceProxy.SayHelloMSMQ("Frank Xu Lei");
(4)運行結果:
首先是客戶端發送到的消息,我們可以再計算機-管理-服務-專用隊列裡查看 到,如圖:
以前的服務要求我們必須啟動宿主,不然會出現連接錯誤。這裡為了測試, 停留約4分鐘後,我們啟動宿主。觀察宿主打印的消息:
宿主在聯機以後響應了客戶端的調用操作。
【總結】
本節文章主要講解的是WCF 如何使用MSMQ開發離線服務操作。這裡除了回顧 了MSMQ的基本概念,還介紹了WCF服務使用MSMQ的通信框架的優勢和特點。最後 給出了基於WCF 消息隊列的離線服務調用實現的過程。
WCF 對MSMQ消息隊列的支持和擴展,大大提高了WCF服務調用的伸縮性和靈活 性。本文由於開發環境的關系,沒有給出公共隊列的開發實現過程。另外在WCF 消息隊列開發過程中,大家要做注意。
(1)在服務宿主端啟動宿主,要做隊列存在的判斷,以免出現讀取錯誤。
(2)隊列服務涉及到安全的問題,認證和消息加密,簽名,需要證書的配置 。條件限制這裡就沒有給出具體的實現過程。
(3)WCF隊列服務的另外一個重要概念就是對離線事務的支持。這一特性會 在後續文章裡給出。
(4)運行環境:Xp pro,.net 3.0以上,vs2008,至少安裝MSMQ隊列的私有 隊列組件服務。
最後給出本文的參考代 碼:配套源碼。