最近研究了一下基于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