【踩坑(Running)填坑(ZSSURE)】:WCF学习之InstanceContextMode与ConcurrencyMode

原创 2015年11月19日 09:08:42

背景:

WCF可以看作是微软对SOA架构的一种实现,或者说WCF的存在让开发者更容易创建面向服务的程序。面向服务本身不是一种技术,而是设计和实现软件的一种架构方式。从最早的面向过程(PO)、面向对象编程(OO),到后来的面向服务(SO)、面向资源(RO)编程,本身没有本质区别,反映出的是人们认识世界的方法论的迭代进化。
PO、OO、SO、RO,还有一个不沾边的O2O,各种概念层出不穷,在学习使用时要切忌混淆。今天这里记录的是在WCF框架下(面向服务架构——SOA——的一种实现),如何进行多线程及并发管理。多线程、并发、加锁、生命周期,这些知识都是老生常谈,剖开新框架的外衣,其本质是没有变化的。

WCF概念介绍:

在进入正题之前,先介绍WCF框架中几个主要概念。

1.EndPoint

WCF通过终结点EndPoint来发布服务,终结点EndPoint包括ABC三要素:
这里写图片描述
这里可以用常见的互联网服务来简单对比一下,Address就是我们使用的URL、Binding就是HTTP或HTTPS协议,Contract就是GET、POST等各种方法。互联网服务端最最常见的就是Apache Httpd、Apache Tomcat、JBoss等各种容器托管服务软件,由于HTTP协议是无状态协议,因此我可以简单的理解为每一次、每一个用户请求服务端都会创建单独的、新的一个响应对象(例如Servlet对象)来处理用户请求,这就跟我们下面要讲到的实例(Instance)和会话(Session)有关。

2.Instance vs Session

看一下实例(Instance)与会话(Session)两者的对比,

概念 含义 备注
实例(Instance) WCF中的实例管理旨在解决服务实例的激活和服务实例生命周期的控制 实例上下文是对服务实例的封装,是WCF管理服务实例的生命周期的依托。
会话(Session) 会话的目的在于保持相同客户端(服务代理)多次服务调用的状态
会话通过消息识别机制判断调用某个服务的消息来源,从而将来自于同一个客户端的消息关联在一起

【备注】:关于生命周期最容易想到的就是Java或C#中的垃圾回收,而这两种主流商用语言都采用了“跟搜索算法”,详情参见《深入理解Java虚拟机:JVM高级特性与最佳实践》

WCF实例模式与并发模式的对比

高性能(Performance)和高伸缩性(Scalability),是软件设计与架构中永远不可以同时兼顾的,原因很简单,高性能往往需要充足的资源,高扩展性又需要尽可能的节约资源。所以我们才说,软件设计与架构是一项“权衡”的艺术。
虽然在前文中对比了会话与实例的概念,但是具体应用中会话与实例往往是分不开的,会话过程中必然用到实例来进行请求处理。通过对比WCF中实例上下文模式与并发模式,以及最后给出具体的示例程序,来了解一下WCF是如何兼顾高性能和高伸缩性的。

1. 实例上下文模式:InstanceContextMode

WCF的实例上下文模式InstanceContextMode分为以下三种,

实例上下文 说明
单调模式(Per-Call) 决定于单调实例上下文模式,即InstanceContextMode
单例模式(Single) 决定于单例实例上下文模式,即InstanceContextMode
会话模式(Per-Session) 取决于会话实例上下文模式、会话信道、会话信道栈,即有会话模式、绑定、实例上下文模式的三者决定,如下图所示:这里写图片描述

服务实例的创建过程,其中会使用反射这样相对影响性能的操作,但是在WCF应用中,真正影响性能的是操作时信道的创建和释放。服务实例的激活和他们比起来,可以说微不足道。如果在应用中出现对基于相同服务代理的频繁调用,比如服务调用放在一个for循环中调用上百次,服务实例的创建带来的性能损失就不能不考虑了。

2. 并发模式:ConcurrencyMode

这里写图片描述

这里写图片描述

这里写图片描述

注:截图来自《WCF全面解析(下册)》,作者蒋金楠

WCF实例模式与并发模式的对比实例测试

1. 设置InstanceContextMode=Single,ConcurrencyMode=Single

这里写图片描述
由上图可以看出,在WCF服务包含回调并且InstanceContextMode与ConcurrencyMode同时设置为Single后,会弹出死锁问题,该问题原因在于服务端的InstanceContext实例在响应客户端请求后会发起回调请求,而此时客户端恰恰在等待服务端的返回结果才能启动回调函数,因此导致两者死锁。解决方案如下。

2. 设置InstanceContextMode=Single,ConcurrencyMode=Reentrant

客户端与服务端显示结果如下,
这里写图片描述
由上图可以看出InstanceContextMode标明的是WCF创建InstanceContext的个数,此处设置为Single指的是所有客户端的请求都由同一个InstanceContext来执行,虽然客户端使用了ThreadPool.QueueUserWorkItem发起并发请求,但是在服务端的实际运行过程中是串行执行的,为了更好的观察执行流程,绘制执行时间简图如下:
这里写图片描述
【注意】:为何Reentrant能够解决死锁问题,可以看考一下《WCF全面解析(下册)》,截图如下:

这里写图片描述

这里写图片描述

【zssure】:有上述可知,Single对实例上下文的加锁是完整的,直到此次服务请求完成(包括请求、回调、回调响应、回调后操作);而Reentrant在发起回调后会释放锁,当然此时如果由其他的客户端使用了该实例上下文,回调响应需要等到其他客户端释放该实例上下文后方可运行,此时如果超时就会抛出异常。上图自己绘制的时间图中将服务端的InstanceContext分化成了两个实例,一个用于正常请求,一个用于回调,其目的是为了更清晰的标明整个响应流程。至于WCF底层是如何来实现同时响应新的客户端请求以及发起回调请求的有待进一步核实。

3. 设置InstanceContextMode=Single,ConcurrencyMode=Multiple

这里写图片描述
正如《WCF全面解析(下册)》书中所言,将ConcurrencyMode设置为Multiple后,服务端的InstanceContext实例可以同时并发响应多个客户端的请求,实现真正意义上的并发。

4. 设置InstanceContextMode=PerCall,ConcurrencyMode=Multiple

再次将InstanceContextMode设置为PerCall查看一下运行结果,如下所示:
这里写图片描述
由此可以看出与第3中情况是相同的,但是此时如果在控制台中间InstanceContext具体实例的HashCode打印出来会发现,三次客户端请求会在服务端创建三个InstanceContext实例,这是与上面第3中情况不同的地方。

总结

由此可以看出InstanceContextMode主要控制的是服务端如何创建具体的实例对象,而ConcurrencyMode控制的是实例与客户端请求之间的分发方式。如下图所示:
这里写图片描述
在WCF中通过实例上下文模式InstanceContextMode的设置来确定服务响应时如何创建具体的操作实例(Instance),另外通过并发模式ConcurrencyMode来控制客户端请求与具体操作实例之间的分发和响应机制。——而这整个过程都可以简单归属为会话层。




作者:zssure@163.com
时间:2015-11-19

版权声明:本文为zssure原创文章,转载请注明出处,未经允许不得转载。

WCF:并发模型(ConcurrencyMode)

1. 什么是WCF并发问题 并发指的是,一个服务实例的成员被多个请求同时进行访问并且修改的可能性及其影响   2. 什么时候会发生并发问题 根据实例模型的不同,我们大致可以分解为 Single和Pe...
  • chen_xizhang
  • chen_xizhang
  • 2009年12月19日 14:07
  • 1704

WCF分布式3-InstanceContext和ConcurrencyMode

WCF中,如果将实现契约(接口)的服务配置默认为 InstanceContextMode = InstanceContextMode.Single, 也就是说这个服务对象,客户端调用这个对象的接口...
  • daigualu
  • daigualu
  • 2017年08月24日 15:29
  • 113

WCF学习之InstanceContextMode与ConcurrencyMode博文源码

  • 2015年11月19日 09:15
  • 25KB
  • 下载

踩坑(Running)填坑(ZSSURE):WCF技术初步应用

背景:近期由于项目需要,开始学习和使用WCF技术。初次涉猎一种陌生技术领域,最常见的就是踩“坑”了。虽然之前浏览和阅读了很多WCF资料,但是在项目实际开发过程中,还是遇到了这样和那样的问题。因此决定在...
  • zssureqh
  • zssureqh
  • 2015年04月08日 23:13
  • 1169

WCF并发(Concurrency)的本质:同一个服务实例上下文(InstanceContext)同时处理多个服务调用请求

http://www.cnblogs.com/artech/archive/2010/03/19/1690118.html 引言 服务(Service)的本质就是提供服务消费者期望的某...
  • mituan1234567
  • mituan1234567
  • 2015年02月12日 15:03
  • 639

WCF学习——掀开你的盖头来

WCF作为一种框架,简单易用的编程方式是一把双刃剑,一方面它让新手非常容易上手,但另一方面,过于简单的模型使得它的使用者不明白其中的细节,因此要用好它并不容易,比如很多时候我们写的WCF程序看起来服务...
  • u010168160
  • u010168160
  • 2015年02月10日 08:01
  • 2193

构建RESTful风格的WCF服务

RESTful Wcf是一种基于Http协议的服务架构风格。 相较 WCF、WebService 使用 SOAP、WSDL、WS-* 而言,几乎所有的语言和网络平台都支持 HTTP 请求。 REST...
  • dyllove98
  • dyllove98
  • 2013年07月22日 20:00
  • 4803

【Android】基于 Android 和 WCF 技术的APP开发技术简述

这里讲述的是开发过程中最基本的,也是做常见的问题。如何开发?怎么开发?适合想要了解安卓客户端和服务器的同学学习。...
  • LIUHUAN0520
  • LIUHUAN0520
  • 2016年09月23日 19:46
  • 3509

WCF 大数据传输问题

当客户端传输的参数中有字节流或者是长度过大的时候,wcf就会报错。出现maxReceivedMessageSize异常解     当使用WCF的客户端调取的数据过多时,会出现这个异常。一般情况下,系...
  • anbailong
  • anbailong
  • 2016年04月25日 17:41
  • 1326

WCF之各种WCF引用方式

写在开头:本文内容来自 WCF全面解析中的一个经典例子,如果你已经看过了,那么可以忽略本文,本文旨在和大家分享不一样的WCF使用方法。 准备工作: 1.创建解决方案WCFService(当然名字可...
  • dyllove98
  • dyllove98
  • 2013年07月30日 18:54
  • 13001
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【踩坑(Running)填坑(ZSSURE)】:WCF学习之InstanceContextMode与ConcurrencyMode
举报原因:
原因补充:

(最多只允许输入30个字)