最近研究了一下基於MSMQ的WCF應用,從書上、網上查了不少資料,但始終沒能完全理解WCF-MSMQ的工做原理,也沒能獲得一個合理的應用解決方案。索性仍是本身作個實驗,探索一下吧。通過反覆試驗,很有收穫,現跟你們分享一下。服務器
首先個人解釋一下爲何查了那麼多資料卻未能理解WCF-MSMQ的工做原理,不是各位大牛沒有把原理講清楚,而是大多數給出的例子都是在單機上運行的,這就很難說明白離線工做的原理。負載均衡
爲了說明問題,我用了四臺虛機來部署個人實驗程序,首先我給你們看一下個人程序部署結構:spa
4臺虛機(紅線表示消息流向),它們的操做系統都是Windows2008 R2,而且都須要安裝MSMQ服務,不然沒法工做。也就是說,若是應用程序客戶端發佈出去之後,要想實現離線提交,在客戶端機器上也必須安裝MSMQ服務。操作系統
接下來看一下WCF程序的配置:3d
服務端code
<system.serviceModel> <bindings> <netMsmqBinding> <binding name="msmqBinding" queueTransferProtocol="Srmp"> <security mode="None" /> </binding> </netMsmqBinding> </bindings> <services> <service name="WCF.Msmq.MsmqService"> <endpoint address="net.msmq://10.222.114.78/private/myqueue" binding="netMsmqBinding" bindingConfiguration="msmqBinding" contract="WCF.Msmq.IMsmqService" /> </service> </services> </system.serviceModel>
客戶端 blog
<system.serviceModel> <bindings> <netMsmqBinding> <binding name="netMsmqBinding" queueTransferProtocol="Srmp"> <security mode="None" /> </binding> </netMsmqBinding> </bindings> <client> <endpoint address="net.msmq://10.222.114.78/private/myqueue" binding="netMsmqBinding" bindingConfiguration="netMsmqBinding" contract="WCF.Msmq.IMsmqService" name="msmqserivce" /> </client> </system.serviceModel>
有一點須要指出,那就是Address。和其它綁定方式不一樣,使用MSMQ的WCF的地址並非本機IP(你們能夠看到個人WCF Host這臺機器的IP是10.222.114.76,像咱們經常使用的basicHttpBingding,WSHttpBingDing等地址指向都是本機地址),而是MSMQ Host那臺虛機的IP地址。這就是我爲何把專門用MSMS Host單獨拿出來做爲消息服務器的緣由。另外, queueTransferProtocol="Srmp"用的使用 SOAP 可靠消息傳送協議 (SRMP),須要安裝HTTP支持,能夠直接把它刪掉使用默認的Native方式。隊列
這裏代碼我就不往上貼了,看一下執行過程吧,WCF Client 1,WCF Client 2往MSMQ Host這臺機器上發送消息,WCF Host監控MSMQ Host這臺機器上的private/myqueue對列,一旦有消息,則把消息提取出來進行處理。下面是個人程序運行結果,在運行程序以前,須要在MSMQ Host上建立一個私有隊列private/myqueue。部署
WCF Client 1執行結果 | WCF Client 2執行結果 | WCF Host 執行結果 |
咱們接下來看下離線工做。咱們把WCF Client 1的網卡禁用,或者停掉MSMQ Host,會看到如下結果,在Outgonging隊列裏堆積了不少發不出去的消息。這就是爲何在客戶端須要安裝MSMQ服務的緣由。一旦WCF Client 1與MSMQ Host再次創建鏈接,在Outgoing隊列裏的消息就會被髮送到MSMQ Host上去。get
關閉WCF Host中咱們運行的Service程序,這時會看到,在MSMQ Host這臺機器上private/myqueue對列中的消息越積越多。等到再次啓動Service後,它裏面的消息就會被處理掉。
通過上面的實驗,能夠獲得一下結論:WCF Host,MSMQ Host,WCF Client這三臺機器任何一臺發生故障,應用都是可恢復的,並且數據不會丟失。
接下來我還作了另外一個實驗,就是在另一臺機器上啓動新建的WCF服務程序,發現兩個Service均可以去處理同一隊列中的消息,從這種意義上來講,這不失是一個負載均衡的一個解決方案。
最後,附上個人實驗代碼,供你們參考:Msmq.7z