WCF分布式開發(fā)步步為贏(13):WCF服務離線操作與消息隊列MSMQ
之前曾經(jīng)寫過一個關于MSMQ消息隊列的文章:WCF分布式開發(fā)必備知識(1):MSMQ消息隊列 ,當時的目的也是用它來作為學習WCF 消息隊列MSMQ編程的基礎文章。在那篇文章里,我們詳細介紹了MSMQ消息隊列的基本概念、安裝、部署、開發(fā)、調試等相關問題。今天我們來學習WCF分布式開發(fā)步步為贏(13):WCF服務離線操作與消息隊列MSMQ。在WCF框架下使用MSMQ消息隊列服務編程。 這里我會給出一個使用WCF MSMQ實現(xiàn)離線請求的DEMO示例程序。
全文結構是:【1】MSMQ基本概念【2】WCF消息隊列MSMQ的優(yōu)勢【3】WCF 消息隊列MSMQ通信框架【4】安裝配置注意事項【5】示例代碼 【總結】
【1】MSMQ基本概念:
簡要回顧一下MSMQ的基本概念,詳細的你們可以參考WCF分布式開發(fā)必備知識(1):MSMQ消息隊列。
MSMQ全稱MicroSoft Message Queue,微軟消息隊列,是在多個不同的應用之間實現(xiàn)相互通信的一種異步傳輸模式,相互通信的應用可以分布于同一臺機器上,也可以分布于相連的網(wǎng)絡空間中的任一位置。它的實現(xiàn)原理是:消息的發(fā)送者把自己想要發(fā)送的信息放入一個容器中(我們稱之為Message),然后把它保存至一個系統(tǒng)公用空間的消息隊列(Message Queue)中;本地或者是異地的消息接收程序再從該隊列中取出發(fā)給它的消息進行處理。
【2】WCF消息隊列MSMQ的優(yōu)勢:
消息隊列MSMQ的優(yōu)點:穩(wěn)定、消息優(yōu)先級、脫機能力以及安全性,有保障的消息傳遞和執(zhí)行許多業(yè)務處理的可靠的防故障機制。 因此消息隊列是實現(xiàn)SOA面向服務架構的重要組件之一。WCF框架提供了和MSMQ集成與擴展的能力。這一點也是WCF在特性中明確指出的。MSMQ支持離線消息模式,而且在WCF框架下,提供了基于http橋的internet網(wǎng)絡隊列服務的調用擴展。和MSMQ框架的結合和擴展,使得WCF服務具有的新的特點:
【2.1】Availabiliy:可用性。這個是MSMQ離線消息的一種體現(xiàn)。客戶單和服務端不需要實時進行連接,然后進行消息的交互.WCF 客戶端可以發(fā)送請求到離線服務端,服務上線以后在相應客戶端請求。
【2.2】Disjoint:分解。可以講工作分解為多個操作,一次放入隊列。改善系統(tǒng)的可用性和吞吐量。
【2.3】Compensating:補償。對于多業(yè)務事務,可以提供單獨的事物提供其它事務失敗的善后處理。
【2.4】Load Leveling:負載平衡。可以把過載的客戶端請求放入隊列,空閑的時候進行處理,平衡系統(tǒng)的吞吐量,改善性能。
【3】WCF 消息隊列MSMQ通信框架:
WCF使用NetMsmqBinding來支持消息隊列通信。當客戶端調用服務時,客戶端消息會被封裝為MSMQ消息,發(fā)送懂到特定的消息隊列。服務端宿主在運行轉臺下會,啟動通道偵聽器,來檢測消息隊列消息,如果發(fā)現(xiàn)對應的消息,會從隊列里取出消息,使用分發(fā)器轉發(fā)給對應的服務。具體的通信架構如圖:

如果宿主離線,消息會被放入隊列,等待下一次宿主聯(lián)機時,在執(zhí)行消息分發(fā)處理,給指定的WCF服務。
【4】安裝配置注意事項:
MSMQ隊列幾種常見的類型就是:
1.公共隊列:在整個消息隊列網(wǎng)絡中復制,并且有可能由網(wǎng)絡連接的所有站點訪問。
2.專用隊列:不在整個網(wǎng)絡中發(fā)布。相反,它們僅在所駐留的本地計算機上可用。專用隊列只能由知道隊列的完整路徑名或標簽的應用程序訪問。
3.管理隊列:包含確認在給定“消息隊列”網(wǎng)絡中發(fā)送的消息回執(zhí)的消息。指定希望 MessageQueue 組件使用的管理隊列(如果有的話)。
4.響應隊列:包含目標應用程序接收到消息時返回給發(fā)送應用程序的響應消息。指定希望 MessageQueue 組件使用的響應隊列(如果有的話)。
這里有幾個問題要注意,以前很多人也在配置MSMQ開發(fā)環(huán)境的時候遇到這個問題。Xp環(huán)境下作MSMQ配置開發(fā)有很多限制。這里算是做個總結供大家參考:
1.公共隊列需要域控制器DC Domain Controller;
2.私有隊列與托管的機器同屬本地,不需要DC,成為工作組安裝;
3.私有隊列需要禁用安全模式:工作組安裝與安全,安全設置需要客戶端提供證書,MSMQ傳輸安全需要使用Windows安全,這里需要使用AD活動目錄。
【5】示例代碼 :
今天的示例DEMO程序代碼,主要演示的是WCF如何配置和開發(fā)一個MSMQ服務程序,實現(xiàn)WCF離線操作,MSMQ事務的部分由于內容較多,這里暫時不涉及。我們只討論WCF離線操作。
(1)WCF服務代碼:
值得注意的WCF的操作要被定義為單向操作,因為本質上其符合單向操作的特征。異步,離線。無返回值。配置操作契約的時候要添加IsOneWay屬性。代碼如下:
[ServiceContract(Namespace = "http://www.rzrgm.cn/frank_xl/")]
public interface IWCFMSMQService
{
//操作契約,必須為單向操作
[OperationContract(IsOneWay = true)]
void SayHelloMSMQ(string name);
}
//2.服務類,繼承接口。實現(xiàn)服務契約定義的操作
public class WCFMSMQService : IWCFMSMQService
{
public WCFMSMQService()
{
Console.WriteLine("WCF MSMQ Service instance was created at:{0}", DateTime.Now);
}
//實現(xiàn)接口定義的方法
public void SayHelloMSMQ(string name)
{
Console.WriteLine("Hello! {0},Calling WCF MSMQ Service Operation at:{1}", name,DateTime.Now);
}
}
(2)宿主:
我的開發(fā)環(huán)境為XP專業(yè)版,工作組模式。這里有個問題要注意,就是安全。MSMQ默認的安全模式是需要證書支持。我們必須在宿主配置文件里給配置為none,簡化操作,因為證書需要MSMQ域管理器。MSMQ傳輸安全需要Windows安全,這個又需要AD活動目錄支持,工作組模式下不支持,因此這里我們都設置為none。代碼如下:
<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秒調用一次服務請求。我們這里在宿主端打印了時間。客戶端發(fā)送消息完畢以后,宿主暫時不啟動。等待一段時間。在啟動宿主,觀察宿主打印的消息。代碼如下:
WCFMSMQServiceClient wcfServiceProxy = new WCFMSMQServiceClient("NetMsmqBinding_IWCFMSMQService");
//通過代理調用SayHello服務,這里及時服務調用服務失敗,消息會發(fā)送到隊列里進行緩存。
Console.WriteLine("WCF First Call at:{0}",DateTime.Now);
wcfServiceProxy.SayHelloMSMQ("Frank");
Thread.Sleep(2000);//客戶端休眠兩秒,繼續(xù)下一次調用
Console.WriteLine("WCF Second Call at:{0}", DateTime.Now);
wcfServiceProxy.SayHelloMSMQ("Frank Xu");
Thread.Sleep(2000);//客戶端休眠兩秒,繼續(xù)下一次調用
Console.WriteLine("WCF Last Call at:{0}", DateTime.Now);
wcfServiceProxy.SayHelloMSMQ("Frank Xu Lei");
(4)運行結果:
首先是客戶端發(fā)送到的消息,我們可以再計算機-管理-服務-專用隊列里查看到,如圖:
以前的服務要求我們必須啟動宿主,不然會出現(xiàn)連接錯誤。這里為了測試,停留約4分鐘后,我們啟動宿主。觀察宿主打印的消息:

宿主在聯(lián)機以后響應了客戶端的調用操作。
【總結】
本節(jié)文章主要講解的是WCF 如何使用MSMQ開發(fā)離線服務操作。這里除了回顧了MSMQ的基本概念,還介紹了WCF服務使用MSMQ的通信框架的優(yōu)勢和特點。最后給出了基于WCF 消息隊列的離線服務調用實現(xiàn)的過程。
WCF 對MSMQ消息隊列的支持和擴展,大大提高了WCF服務調用的伸縮性和靈活性。本文由于開發(fā)環(huán)境的關系,沒有給出公共隊列的開發(fā)實現(xiàn)過程。另外在WCF 消息隊列開發(fā)過程中,大家要做注意。
(1)在服務宿主端啟動宿主,要做隊列存在的判斷,以免出現(xiàn)讀取錯誤。
(2)隊列服務涉及到安全的問題,認證和消息加密,簽名,需要證書的配置。條件限制這里就沒有給出具體的實現(xiàn)過程。
(3)WCF隊列服務的另外一個重要概念就是對離線事務的支持。這一特性會在后續(xù)文章里給出。
(4)運行環(huán)境:Xp pro,.net 3.0以上,vs2008,至少安裝MSMQ隊列的私有隊列組件服務。
最后給出本文的參考代碼:/Files/frank_xl/WCCFServiceMSMQFrankXuLei.rar。


浙公網(wǎng)安備 33010602011771號