雪花

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()
});

 

posted @ 2019-07-02 11:32  十色  阅读(1756)  评论(1编辑  收藏  举报