WCF Throttling 限流的三道闸口
WCF Throttling 限流的三道闸口
一、WCF Throttling 流量限制简介
我们期望WCF服务端能够处理尽可能多的并发请求,但是资源是有限的,服务不可能同时处理无限多的并发请求,如果WCF不控制进入消息处理系统的并发量,一旦超过临界值,整个服务端将会由于资源耗尽而崩溃,所以WCF提供了一个限流Throttling特性,让我们可以根据不同性能的服务器来配置最佳的并发流量限制,这三个值相当于WCF通道的三个闸口,每个值代表各自闸口的计数器,当各闸口监控的计数达到你所设置的阈值,后续的请求将会进入到服务的等待队列,所以,如果此值设置过小了,则大量并发请求时不能被及时处理而进入到等待队列中,很容易出现超时的情况,如果值设置过大,则会出现WCF处理不过来的情况,容易导致服务崩溃,所以,对于高低配置处理能力不同的服务器,需要分别设置阈值。
二、Throttling三个流量阈值简介
通过反编译和MSDN帮助得知,三个属性解释和默认值如下:
MaxConcurrentCalls |
该值指定整个 ServiceHost 中正在处理的最多消息数 |
16 * CPU核心数 |
MaxConcurrentSessions |
指定 ServiceHost 对象可一次接受的最多会话数的值 |
100 * CPU核心数 |
MaxConcurrentInstances |
该值指定服务中可以一次执行的最多 InstanceContext 对象数 |
MaxConcurrentCalls+MaxConcurrentSession |
从System.ServiceModel.dll 反编译的代码来看,默认值的逻辑确实如此。
但,你可能会想,一个ServiceHost默认正在处理的消息数才16,未免太少了吧,别担心,反编译代码再细看可知,MaxConcurrentCalls和MaxConcurrentSessions的默认值与CPU核数是相关的,假如你的系统配置是4核电脑,则MaxConcurrentCalls默认值等于16*4,MaxConcurrentSessions默认值等于 100*4,maxConcurrentInstances默认值等于64+400,假如你对此默认值还觉得不适当,需要显式设置的话,建议以默认值为准绳进行增减设置,MSDN Library 的建议是设置比16 * cpu核数要大的数值,总的来说,阈值设置多大,还需根据生产环境情况和经验来把握,值得注意的是,显式配置的时候,值是需要是经过与cpu核心数乘法计算后的值,因为WCF不会再去乘以你所显式设定的值的。
一个完整的ServiceThrottling配置如下,如采取默认,则将<ServiceThrottling>节点去掉,你也可以单独只设定某个属性,其他属性则自动采用默认值,除了以配置的形式外,还可以通过代码来进行设定,这里不做叙述。
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceThrottling maxConcurrentCalls="16" maxConcurrentSessions="100" maxConcurrentInstances="116"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
三、maxConcurrentCalls:使用windows性能监视器验证配置效果
我在研究ServiceThrottling特性的时候搜了很多资料,发现很少,几乎是没有一篇是说三个流量阈值该设置多少才合适、如何去验证配置前后的效果等,这让我当时有一种感叹:世界上最难的事情并不是找出正确的答案,而是让你找出证明你答案是正确的证据。
后来发现使用windows的性能监视器可以监控到WCFService的执行情况,我使用的是ServiceModelService 4.0.0.0 的Calls OutStanding计数器,能监控正在进行的调用的次数,其他关于WCF的计数器请参阅文末的参考资料;Windows性能监视器可以在管理工具->性能监视器 打开,除了实时监控外,还可以生成日志文件,实乃监控运维的一大利器,关于性能监视器的详细用法请自行搜索资料。
我的测试服务接口所做的操作是,Thread.Sleep 3秒,然后客户端大量并发请求,通过修改MaxConCurrentCalls的值观察实验效果:
1、 当将MaxConcurrentCalls设置为1的时候,服务将以串行化执行,监控结果显示正在进行的调用次数一直都为1;
2、 当将MaxConcurrentCalls设置为30的时候,WCF服务的处理能力明显提到,当调用次数在提升阶段时,证明WCF的处理能力在预设的阈值之内,当达到峰顶阈值30后,后续来的请求发现此时的WCF同时处理请求的能力已经达到预设的阈值了,就会进入到等待队列中去,等待调度,当等待队列中的请求慢慢被处理完后,此时计数器也会进行减法处理,以便让后续来的请求知道,你这个服务到底有没有能力马上“接待”我,从下图可以看出,如果MaxConCurrentCalls设置过小的话,就会很容易限制了WCF的处理能力,出现瓶颈。
四、maxConcurrentSessions:借用蒋金楠博客中的例子来说说
maxConcurrentSessions的作用是指定 ServiceHost 对象可一次接受的最多会话数的值,默认值为100 * CPU核心数,所以,我们的测试示例使用的接口Binding必须是支持Session的,不能使用basicHttpBinding,因为他不支持session会话,如果Binding不支持会话,则此属性的设置也就无效了,这里我使用的Binding是wsHttpBinding。
using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>("calculatorservice"))
{
bool stop = false;
for (int i = ; i < && !stop; i++)
{
ICalculator calcultor = channelFactory.CreateChannel();
try
{
calcultor.Add(, );
Console.WriteLine("第{0}个服务代理调用成功!", i + );
}
catch (Exception ex)
{
Console.WriteLine("出现异常:{0}", ex.Message);
stop = true;
}
}
}
我们通过基于客户端终结点配置名称创建的ChannelFactory<TChannel>对象创建了1000个服务代理进行用其进行1000次服务调用。当上面这个实例运行的时候,客户端控制台将会出现如下的输出结果,实例程序清晰地反映了这样的事实:虽然我们通过不同的服务代理对象进行了1000次服务调用,但是只有前面400是成功的,第401个请求将一直等待被处理,直到达到超时时间为止,在这里我没有配置maxConcurrentSessions值,所以限流阈值采用的是默认值100 乘以我的电脑CPU核心数4,也就是400。
在这里对蒋金楠表示感谢,不仅仅是在查询WCF相关资料的时候经常会搜到你的文章,对我有很大的帮助,而且上次你在博客园发起的整点抢评论赠书活动中送了我一本《ASP.NET Web API 2 框架揭秘》,据说很快会做一个《ASP.NET MVC5 框架揭秘》的抢评活动!
五、maxConcurrentInstances
MSDN:MaxConcurrentInstances 属性指定服务中 InstanceContext 对象的最大数目。 牢记 MaxConcurrentInstances 属性和InstanceContextMode 属性之间的关系很重要。 如果 InstanceContextMode 为 PerSession,则结果值将为总会话数。 如果InstanceContextMode 为 PerCall,则结果值将为并发调用的数量。 如果消息到达时,InstanceContext 对象的数目已经达到最大数量,则将保存该消息,直至有 InstanceContext 对象关闭。
InstanceContextMode是特性ServiceBehavior中的一个枚举属性,ServiceBehavior特性指定服务协定实现的内部执行行为,一般这样使用。
既然MaxConCurrentInstances与InstanceContextMode关系密切,先来看看这个枚举,很明显PerSession 与PerCall 的区别是,PerSession 为每个会话创建一个新的System.ServiceModel.InstanceContext对象,而PerCall则会在每次调用前创建,调用后回收。
//指定可用来处理包含在传入消息中的调用的服务实例数。
public enum InstanceContextMode
{
//为每个会话创建一个新的 System.ServiceModel.InstanceContext 对象。
PerSession = ,
//新的 System.ServiceModel.InstanceContext 对象在每次调用前创建,在调用后回收。如果信道未创建会话,则该值的行为就如同
PerCall = ,
//只有一个 System.ServiceModel.InstanceContext 对象用于所有传入呼叫,并且在调用后不回收。如果服务对象不存在,则创建一个。
Single = ,
}
六、总结
以上,我们得知WCF的限流特性以及三个限流闸口各自限制的对象,还可以通过Windows性能监视器来监控服务的情况,对于WCF Throttling,我个人建议是让其采取默认的配置,因为其默认值中考虑到了CPU核心数,考虑到了不同配置服务器的情况,而且还可以不必在每台服务器上修改配置,但同时MSDN也提到,WCF Throttling的设置也是需要依靠经验来,所以,如果采用默认配置的情况下出现瓶颈现象和处理能力不足的情况,不妨根据每台服务器的情况,显式增加阈值。
七、参考资料:
乘以CPU核心数的好处就是部署在不同配置的服务器上,都无需再修改配置。
We also bumped up the value for MaxConcurrentSessions from 10 to 100. Based on customer’s feedback, this change fits the need for most applications.
Please note, these changes are for the default settings only. If you explicitly set these settings in either configuration or in code, the system would use the settings that you provided. No “ProcessCount” multiplier would be applied.
* CPU核心数 的改变只适用于默认配置,如果你修改配置的话,就不适用于核心数相乘。需要你自己乘以核心数然后配置上去 。
4、WCF 4.0一个鲜为人知的改变[兼书名征集] http://www.cnblogs.com/artech/archive/2011/12/31/2308627.html
5、控制并发访问的三道屏障: WCF限流(Throttling)体系探秘[下篇] http://www.cnblogs.com/artech/archive/2010/04/14/1712088.html
6、Optimizing WCF Web Service Performance http://msdn.microsoft.com/library/ee377061.aspx
7、WCF中的Binding模型之六(完结篇):从绑定元素认识系统预定义绑定 http://www.cnblogs.com/artech/archive/2008/12/14/1354691.html
8、concurrency-and-throttling-configurations-wcf-services http://devproconnections.com/net-framework/concurrency-and-throttling-configurations-wcf-services
9、WCF中并发(Concurrency)与限流(Throttling)体系深入解析系列[共7篇] http://www.cnblogs.com/artech/archive/2010/04/22/1718188.html
WCF Throttling 限流的三道闸口的更多相关文章
- [WCF编程]9.性能与限流
一.性能概述 WCF服务的性能取决于很多因素.出了CPU.RAM和网络性能等常见的因素外,实例上下文模式.并发模式.数据契约的设计或使用的绑定等与WCF有关的因素都起着重要的作用. 实例上下文模式用来 ...
- WCF 项目应用连载[8] - 绑定、服务、行为 大数据传输与限流 - 下 (ServiceThrottlingAttribute)
因为ORM的原因,对Attribute编程有一种情节..所以这节的出现,完全是因为在WCF对自定义Attribute的一种应用. WCF 项目应用连载[7] - 绑定.服务.行为 大数据传输与限流 - ...
- WCF之并发,吞吐量和限流
并发 Single重入模式.对于每一个服务实例,同一时刻只能处理一个请求,其他对该实例的请求被排队. PerCall,每一线程会分配一个新的服务实例上.不会有并发性问题.不影响吞吐量. PerSess ...
- WCF学习笔记之并发与限流
最近一直在学习WCF相关知识:本文章将针对并发与限流知识进行一个梳理,由于很多理论的知识所以做一个简单的记录,为今后回顾做一个记录: 一:并发知识 WCF将服务实例封装在一个称为实例上下文的对象中,并 ...
- wcf利用IDispatchMessageInspector实现接口监控日志记录和并发限流
一般对于提供出来的接口,虽然知道在哪些业务场景下才会被调用,但是不知道什么时候被调用.调用的频率.接口性能,当出现问题的时候也不容易重现请求:为了追踪这些内容就需要把每次接口的调用信息给完整的记录下来 ...
- drf06 认证Authentication 权限Permissions 限流Throttling
为了方便接下来的学习,我们创建一个新的子应用 four python manage.py startapp four 因为接下来的功能中需要使用到登陆功能,所以我们使用django内置admin站点并 ...
- 45.限流Throttling及源码解析
什么是限流? 限流类似于权限机制,它也决定是否接受当前请求,用于控制客户端在某段时间内允许向API发出请求的次数,也就是频率 假设有客户端(比如爬虫程序)短时间发起大量请求,超过了服务器能够处理的能力 ...
- 快速入门系列--WCF--06并发限流、可靠会话和队列服务
这部分将介绍一些相对深入的知识点,包括通过并发限流来保证服务的可用性,通过可靠会话机制保证会话信息的可靠性,通过队列服务来解耦客户端和服务端,提高系统的可服务数量并可以起到削峰的作用,最后还会对之前的 ...
- WebApiThrottle限流框架使用手册
阅读目录: 介绍 基于IP全局限流 基于IP的端点限流 基于IP和客户端key的端点限流 IP和客户端key的白名单 IP和客户端key自定义限制频率 端点自定义限制频率 关于被拒请求的计数器 在we ...
随机推荐
- C#Light 和 uLua的对比第二弹
上次的对比大家还有印象否,C#Light和ulua对比各有胜负 今天我们加入一个去反射优化,这是uLua没办法实现的优化,我们也就只能不要脸的胜之不武了 以原生执行同一测试时间为X1,数字越小的越快 ...
- 虚拟化平台cloudstack(6)——使用maven:jetty调试
调试环境 ubuntu 12.04 JDK1.7 apache-maven-3.10 eclipse 4.2 Juno mysql 5 apache ant JDK的配置和安装 安装可以参考: htt ...
- QT屏蔽qDebug的方法
在工程文件.pro里面添加 DEFINES += QT_NO_WARNING_OUTPUT\ QT_NO_DEBUG_OUTPUT 然后rebuild all.这样 ...
- Sizeof的计算看内存分配
本文记录了有关sizeof的一些计算,主要有下面的四种情况:(如有错误,敬请留言) 使用sizeof()计算普通变量所占用的内存空间 sizeof计算类对象所占用空间的大小-用到了字节对齐 sixeo ...
- 去除NSString里面的空格
NSString *password = @"12 34"; [password stringByTrimmingCharactersInSet:[NSCharacterSet ...
- Permission is only granted to system apps
原文地址http://jingyan.baidu.com/article/9113f81b2e7a8c2b3314c711.html
- Atitit 函数式编程与命令式编程的区别attilax总结 qbf
Atitit 函数式编程与命令式编程的区别attilax总结 qbf 1.1. 函数式程序就是一个表达式.命令式程序就是一个冯诺依曼机的指令序列. 命令式编程是面向计算机硬件的抽象,有变量(对应着存 ...
- ECMAScript 6 入门
ECMAScript 6 入门 东西真多哇 http://es6.ruanyifeng.com/#docs/module 目录 前言 ECMAScript 6简介 let和const命令 变量的解构赋 ...
- 项目中是用eCharts
1.首先在项目中引入echart.js库. <!DOCTYPE HTML> <%@page contentType="text/html; charset=UTF-8&qu ...
- codeforces B - Preparing Olympiad(dfs或者状态压缩枚举)
B. Preparing Olympiad You have n problems. You have estimated the difficulty of the i-th one as inte ...