WebApiThrottle限流框架
一、WebApiThrottle限流框架
1、Nuget安装(PM)
PM> Install-Package WebApiThrottle
WebApiThrottle支持自定义配置各种限流策略。可以根据不同场景配置多个不同的限制,比如授权某个IP每秒、每分钟、每小时、每天、每周的最大调用次数。 这些限制策略可以配置在所有请求上,也可以单独给每个API接口去配置。
2、WebApiConfig 增加
//WebApiConfig 增加 config.MessageHandlers.Add(new ThrottlingHandler() { Policy = new ThrottlePolicy( perSecond: 1 //可选参数 每秒限制次数 , perMinute: 20 //可选参数 每分钟限制次数 , perHour: 200 //可选参数 每小时限制次数 , perDay: 1500 //可选参数 每天限制次数 , perWeek: 3000 //可选参数 每周限制次数 ) { IpThrottling = true, //该值指示是否启用IP限制 ClientThrottling = true //该值指示是否启用客户端限制 }, Repository = new CacheRepository(), //QuotaExceededMessage = JsonConvert.SerializeObject(json.msg), QuotaExceededContent = (l, obj) => //违反限流事件 { //var json = new JsonResult { code = 0, msg = $"超出规定的频率了,{l}{obj}" }; var json=new { code = 0, msg = $"超出规定的频率了,{l}{obj}" };//匿名Json return (json); } });
然后在新建的控制内添加请求的Action==http://localhost:60288/api/temp
public IEnumerable<string> Get() { yield return DateTime.Now.ToString(); }
默认情况下,被拒绝的请求不会累加到WebApiThrottle的计数器里。 比如一个客户端在同一秒中请求了3次,而你配置的限制策略是每秒1次,那么分钟、小时、天的计数器只会记录第一次调用,因为第一次请求不会被拒绝。如果你想把被拒绝的请求也计算到其他的计数器里(分钟、小时、天),你可以设置StackBlockedRequests为true。
config.MessageHandlers.Add(new ThrottlingHandler() { Policy = new ThrottlePolicy(perSecond: 1, perMinute: 30) { IpThrottling = true, ClientThrottling = true, EndpointThrottling = true, StackBlockedRequests = true //拒绝的请求累加到WebApiThrottle的计数器里 }, Repository = new CacheRepository() });
有的时候我们只需要设置一个参数,每分钟限流次数
//WebApiConfig 增加 config.MessageHandlers.Add(new ThrottlingHandler() { Policy = new ThrottlePolicy( perMinute: 5 )//可选参数 我们仅需要每分钟限制次数 { IpThrottling = true //该值指示是否启用IP限制 ,ClientThrottling = true //该值指示是否启用客户端限制 }, Repository = new CacheRepository(), //QuotaExceededMessage = JsonConvert.SerializeObject(json.msg), QuotaExceededContent = (l, obj) => //违反限流事件 { //var json = new JsonResult { code = 0, msg = $"超出规定的频率了,{l}{obj}" }; var json = new { code = 0, msg = $"超出规定的频率了,{l}{obj}" };//匿名Json return (json); } });
3、使用方式一(EnableThrottlingAttribute特性配置限制频率-围绕controllers和actions去自定义频率限制)
EnableThrottling与ThrottlingHandler是一个二选一的策略配置方案,二者会做同样的事情,但ThrottlingHandler可以通过EnableThrottlingAttribute特性指定某个webapi的controllers和actions去自定义频率限制。需要注意的是,在webapi请求管道中,ThrottlingHandler是在controller前面执行,因此在你不需要ThrottlingFilter提供的功能时,可以用ThrottlingHandler去直接替代它。
设置ThrottlingFilter过滤器的步骤,跟ThrottlingHandler类似:
config.Filters.Add(new ThrottlingFilter() { Policy = new ThrottlePolicy(perSecond: 1, perMinute: 20, perHour: 200, perDay: 2000, perWeek: 10000) { //ip配置区域 IpThrottling = true, IpRules = new Dictionary<string, RateLimits> { { "::1/10", new RateLimits { PerSecond = 2 } }, { "192.168.2.1", new RateLimits { PerMinute = 30, PerHour = 30*60, PerDay = 30*60*24 } } }, //添加127.0.0.1到白名单,本地地址不启用限流策略 IpWhitelist = new List<string> { "127.0.0.1", "192.168.0.0/24" }, //客户端配置区域,如果ip限制也是启动的,那么客户端限制策略会与ip限制策略组合使用。 ClientRules = new Dictionary<string, RateLimits> { { "api-client-key-demo", new RateLimits { PerDay = 5000 } } }, //白名单中的客户端key不会进行限流。 ClientWhitelist = new List<string> { "admin-key" }, //端点限制策略配置会从EnableThrottling特性中获取。 EndpointThrottling = true } });
使用特性开启限流并配置限制频率:
[EnableThrottling(PerSecond = 2)] public class ValuesController : ApiController { [EnableThrottling(PerSecond = 1, PerMinute = 30, PerHour = 100)] public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } [DisableThrotting] public string Get(int id) { return "value"; } }
4、使用方式二(端点自定义限制频率-围绕路由地址去限制频率)
你也可以为明确的路由地址去自定义限制频率,这些限制配置会重写WebApiThrottle的默认配置。也可以通过相关联的路由地址去定义端点的限制规则,比如api/entry/1端点的请求仅仅是/entry/整个路由地址请求的一部分。 配置后,端点限制引擎会在请求的绝对URI中去搜索这个表达式(api/entry/1),如果这个表达式在请求路由策略中被找到,那么这个限制规则将会被应用。如果有两个或更多的限制规则匹配到同一个URL,更近一级的限制策略将会被应用。
config.MessageHandlers.Add(new ThrottlingHandler() { Policy = new ThrottlePolicy(perSecond: 1, perMinute: 20, perHour: 200) { IpThrottling = true, ClientThrottling = true, EndpointThrottling = true, EndpointRules = new Dictionary<string, RateLimits> { { "api/search", new RateLimits { PerSecond = 10, PerMinute = 100, PerHour = 1000 } } } }, Repository = new CacheRepository() });