专栏首页大内老AWCF 4.0一个鲜为人知的改变

WCF 4.0一个鲜为人知的改变

本篇文章介绍可以算是WCF 4.0基于限流(Throttling)的新特性,是在修订《WCF技术剖析(卷1)》的时候编写演示实例的时候发现的。这个特性没有出现在官方文档上面,至少在MSDN上的相关介绍依然是错误的。

一、流量限制简介

WCF是一个基于多线程的消息监听、接收和处理框架体系,能够同时应付来自相同或者不同客户端的服务调用请求,并提供完善的同步机制确保状态的一致性。一方面,我们期望WCF服务端能够处理尽可能多的并发请求,但是资源的有限性决定了并发量有一个最大值。如果WCF不控制进入消息处理系统的并发量,试图处理所有抵达的并发请求,一旦超过了这个临界值,整个服务端将会由于资源耗尽而崩溃。

所以,我们需要在WCF的消息接收系统和消息处理系统之间设置一道道屏障,将流入消息处理系统的请求控制到一个最佳的范围,以实现对现有资源的有效利用,从而达到确保服务的可用性和提高整体吞吐量的目的。WCF的流向限制(Throttling)为你设置了这些屏障,你可以根据现有的软硬件环境对该闸门准入的并发流量进行动态的配置。

WCF对限流的控制是通过一个服务行为(Service Behavior)实现的,该服务行为类型名称为ServiceThrottlingBehavior,定义在System.ServiceModel.Description命名空间下。ServiceThrottlingBehavior定了三个整型的属性:MaxConcurrentCallsMaxConcurrentInstancesMaxConcurrentSessions。它们分别代表流量控制的三个阀值,简单地说,我们所说的限流就是通过设置这三个值控制能够处理的并发量。

二、MSDN关于三个限流阀值的介绍

基于.NET Framework 4.0的MSDN对上述三个限流阀值是这样介绍的:

三、通过实例测试默认的最大并发会话数

通过ServiceThrottlingBehaviorMaxConcurrentSessions属性表示的最大并发会话数默认为10,果真如此吗?我们不妨通过一个简单的实例来验证。照理以计算服务为例,下面是契约接口和服务类型的定义。

   1: [ServiceContract(Namespace ="http://www.artech.com/")]
   2: public interface ICalculator
   3: {
   4:     [OperationContract]
   5:     double Add(double x, double y);
   6: }
   7:  
   8: public class CalculatorService : ICalculator
   9: {      
  10:     public double Add(double x, double y)
  11:     {
  12:         return x + y;
  13:     }
  14: }

我们采用控制台程序对CalculatorService进行寄宿,如下所示的是采用的配置:

   1: <configuration>
   2:   <system.serviceModel>
   3:     <services>
   4:       <service name="Artech.WcfServices.Service.CalculatorService">
   5:         <endpoint  address="http://127.0.0.1:3721/calculatorservice"
   6:                    binding="ws2007HttpBinding"
   7:                    contract="Artech.WcfServices.Service.Interface.ICalculator"/>
   8:       </service>
   9:     </services>
  10:   </system.serviceModel>
  11: </configuration>

从上面的配置中我们知道寄宿的服务具有一个唯一的基于WS2007HttpBinding(支持会话)的终结点。客户端采用相应的配置并通过如下的代码进行服务的调用。

   1: using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>("calculatorservice"))
   2: {
   3:     bool stop = false;
   4:     for (int i = 0; i < 1000 && !stop; i++)
   5:     {
   6:         ICalculator calcultor = channelFactory.CreateChannel();
   7:         try
   8:         {
   9:             calcultor.Add(1, 2);
  10:             Console.WriteLine("第{0}个服务代理调用成功!", i + 1);
  11:         }
  12:         catch (Exception ex)
  13:         {
  14:             Console.WriteLine("出现异常:{0}", ex.Message);
  15:             stop = true;
  16:         }
  17:     }
  18:    }

在上面这段用于进行服务调用的代码中,我们通过基于客户端终结点配置名称创建的ChannelFactory<TChannel>对象创建了1000个服务代理进行用其进行1000次服务调用。当上面这个实例运行的时候,客户端控制台将会出现如下的输出结果。实例程序清晰地反映了这样的事实:虽然我们通过不同的服务代理对象进行了1000次服务调用,但是只有前面两百次是成功的。如果默认的最大并发会话数是10的话,只有前面10次服务调用会成功。

   1: 第1个服务代理调用成功!
   2: 第2个服务代理调用成功!
   3:    ...
   4: 第199个服务代理调用成功!
   5: 第200个服务代理调用成功!
   6: 出现异常:请求通道在等待 00:00:59.9844000 以后答复时超时。增加传递给请求调用的超时值,或者增加绑定上的 SendTimeout 值。分配给此操作的时间可能已经是更长超时的一部分。

四、WCF 4.0中三个限流默认阀值具体是多少呢?

通过上面演示的实例,我们发现默认情况下允许200次并发会话,那么MaxConcurrentSessions的默认值不是10,而是200吗?由于三个限流属性值是通过配置的方式进行指定的,所以要了解它们的默认值,只需要了解对应的配置元素类型的定义即可。下面是ServiceThrottlingBehavior对应的配置元素ServiceThrottlingElement 的定义。

   1: public sealed class ServiceThrottlingElement : BehaviorExtensionElement
   2: {
   3:      //...
   4:     [ConfigurationProperty("maxConcurrentCalls", DefaultValue=0x10)]
   5:     public int MaxConcurrentCalls { get; set; }
   6:  
   7:     [ConfigurationProperty("maxConcurrentInstances", DefaultValue=0x74)]
   8:     public int MaxConcurrentInstances { get; set; }
   9:  
  10:     [ConfigurationProperty("maxConcurrentSessions", DefaultValue=100)]
  11:     public int MaxConcurrentSessions { get; set; }
  12: }
  13:  

从应用在三个配置属性上ConfigurationPropertyAttribute特性可以看出,MaxConcurrentCalls、MaxConcurrentInstances 和MaxConcurrentSessions 的默认值为16、116和100,而不是MSDN所说的16、26和10。

既然MaxConcurrentSessions的默认值为100,那么我们的实例为什么会有200次成功的并发访问呢?原因很简单:这三个限流阀值都是针对单个处理器的,由于运行机器采用双核处理器,自然就是200。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 深入理解C# 3.x的新特性(2):Extension Method[上篇]

    在C#3.0中,引入了一些列新的特性,比如: Implicitly typed local variable, Extension method,Lambda ...

    蒋金楠
  • [原创]深入理解C# 3.x的新特性(3):从Delegate、Anonymous Method到Lambda Expression

    在C#3.0中,引入了一些列新的特性,比如: Implicitly typed local variable, Extension method,Lambda ...

    蒋金楠
  • ASP.NET MVC以ModelValidator为核心的Model验证体系: ModelValidatorProviders

    前面篇文章我们分别介绍用真正用于实施Model验证的ModelValidator(《ASP.NET MVC以ModelValidator为核心的Model验证体...

    蒋金楠
  • 为什么魂斗罗只有 128KB 却可以实现那么长的剧情?

    个人觉得 fc 最神奇的游戏还属超级玛丽,32 个关卡,每关都不同,各种隐藏要素,好像代码区才 10 多 k,数据区 10 多 k。

    良月柒
  • 为什么魂斗罗只有 128KB 却可以实现那么长的剧情?

    个人觉得fc最神奇的游戏还属超级玛丽,32个关卡,每关都不同,各种隐藏要素,好像代码区才10多k,数据区10多k。反汇编看完还是不敢相信这点东西能玩一个童年… ...

    芋道源码
  • linux的简单介绍以及常用简单命令

    例如:需要让张三同学帮忙去楼下小卖铺买一瓶农夫山泉水和清风餐巾纸,在这个指令中“买东西”是指令的主体,买的水和餐巾纸是操作的对象,农夫山泉、清风是操作的选项。|

    踏浪
  • 在类中取得当前文件所在的相对路径与绝对路径

    /**  * <p>Title: 在类中取得当前文件所在的相对路径与绝对路径</p>  *  * <p>Description: 在类中取得当前文件所在的相对路...

    阿敏总司令
  • 基于 Laravel + Vue 组件实现文件异步上传

    我们在上一篇教程中已经演示了如何通过 Request 请求实例获取各种文本输入数据,但是还有一种输入数据我们没有涉及到,那就是文件上传。我们可以通过 Reque...

    学院君
  • Excel 技巧篇-在指定范围内生成指定小数位的随机数

    如果我们想要在指定范围内生成指定小数位的随机数,就需要变形了。 下面我来举两个例子:

    小蓝枣
  • WPF 从 DrawingVisual 转 BitmapImage 图片

    有一些库的设计是需要传入一个 BitmapImage 图片,但是我需要从界面代码创建图片,我没有文件,如何通过 DrawingVisual 画出的控件转换 Bi...

    林德熙

扫码关注云+社区

领取腾讯云代金券