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 ...
随机推荐
- js模版引擎handlebars.js实用教程——with-终极this应用
返回目录 <!DOCTYPE html> <html> <head> <META http-equiv=Content-Type content=" ...
- AutoMapper的简单使用
接触AutoMapper已经有两年多的时间了,在ORM框架中,它使持久层对象与DTO对象之间的转换变得相当简单. 随着负责的项目的增多,使用的技术框架一多起来,很多具体的技术点难免记不清, 加上同时兼 ...
- PHP数据库操作:从MySQL原生API到PDO
本文将举详细例子向大家展示PHP是如何使用MySQL原生API.MySQLi面向过程.MySQLi面向对象.PDO操作MySQL数据库的. 为了后面的测试,先建立数据库表test.包含表名user,s ...
- [Spring框架]Spring JDBCTmplate基础入门总结.
前言:前面有讲过 Spring IOC以及AOP的基本使用方法, 这里就再来讲下Spring JDBCTemplate的使用方法. 一, 概述这里先说一下Spring 整合的一些模板: 从上图中可以看 ...
- java 线程协作 yield()
yield():方法的定义 调用yield方法会让当前线程交出CPU权限,让CPU去执行其他的线程. 但是yield不能控制具体的交出CPU的时间,另外,yield方法只能让拥有相同优先级的线程有获取 ...
- leancloud 用户登录(调用API) 教程
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; ...
- NGUI 可裁剪的灰度Shader
Shader "Custom/Unlit - Transparent Colored Grayed (SoftClip)" { Properties { _MainTex (&qu ...
- JAVA--网络编程(UDP)
上午给大家简单介绍了一下TCP网络通信的知识,现在就为大家补充完整网络编程的知识,关于UDP的通信知识. UDP是一种不可靠的网络协议,那么还有什么使用价值或必要呢?其实不然,在有些情况下UDP协议可 ...
- poj 2226 Muddy Fields(合理建图+二分匹配)
/* 题意:用木板盖住泥泞的地方,不能盖住草.木板任意长!可以重叠覆盖! '*'表示泥泞的地方,'.'表示草! 思路: 首先让我们回忆一下HDU 2119 Matrix这一道题,一个矩阵中只有0, 1 ...
- Hard Drive Inspector Pro 4.26.208(硬盘检测工具)简体中文特别版
Hard Drive Inspector监视硬盘错误并且接收警报,检查变化并实施诊断.例如:驱动器旋转时间增加以及数次重试才能运转驱动器通常意味着发动机和/或者轴存在可以导致数据丢失的错误.HardD ...