Dnc.Api.Throttle

  

适用于Dot Net Core的WebApi接口限流框架

使用Dnc.Api.Throttle可以使您轻松实现WebApi接口的限流管理。Dnc.Api.Throttle支持IP、用户身份、Request Header、Request QueryString等多种限流策略,支持黑名单和白名单功能,支持全局拦截和单独Api拦截。

Dnc.Api.Throttle暂时只支持Redis作为缓存和存储库,后续会进行扩展。

开始使用

  • 安装Dnc.Api.Throttle

    NuGet:PM> Install-Package Dnc.Api.Throttle

  • 基本配置

    Startup.cs:

        public void ConfigureServices(IServiceCollection services){//Api限流services.AddApiThrottle(options => {//配置redis//如果Cache和Storage使用同一个redis,则可以按如下配置options.UseRedisCacheAndStorage(opts => {opts.ConnectionString = "localhost,connectTimeout=5000,allowAdmin=false,defaultDatabase=0";//opts.KeyPrefix = "apithrottle"; //指定给所有key加上前缀,默认为apithrottle
                });//如果Cache和Storage使用不同redis库,可以按如下配置//options.UseRedisCache(opts => {//    opts.ConnectionString = "localhost,connectTimeout=5000,allowAdmin=false,defaultDatabase=0";//});//options.UseRedisStorage(opts => {//    opts.ConnectionString = "localhost,connectTimeout=5000,allowAdmin=false,defaultDatabase=1";//});
            });services.AddMvc(opts => {//这里添加ApiThrottleActionFilter拦截器opts.Filters.Add(typeof(ApiThrottleActionFilter));}).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);}public void Configure(IApplicationBuilder app, IHostingEnvironment env){...//Api限流
            app.UseApiThrottle();app.UseMvc();}

  • 给Api添加一个限流阀门(Valve)

    ValuesController.cs:

        // GET api/values
        [HttpGet][RateValve(Policy = Policy.Ip, Limit = 10, Duration = 30)]public ActionResult<IEnumerable<string>> Get(){return new string[] { "value1", "value2" };}

    以上特性代表给Get接口添加一个速率阀门,指定每个IP,30秒内最多调用10次该接口。

  • 通过以上配置,最简单的一个接口限流就完成了。

    当Api被拦截时,接口不会执行,context.Result会返回一个 new ApiThrottleResult { Content = "访问过于频繁,请稍后重试!" }, ApiThrottleResult继承于ContentResult,你可以不继续处理,也可以在自己的ResultFilter中拦截ApiThrottleResult并处理。

更多Valve范例

  • [RateValve(Policy = Policy.UserIdentity, Limit = 1, Duration = 60)]

    代表根据用户身份,每60秒可访问1次该接口。关于用户身份,默认是如下取得的:

        return context.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;

    如果需要自定义,则可以在Startup.cs中如下配置:

           //Api限流services.AddApiThrottle(options => {...options.OnUserIdentity = (httpContext) =>{//这里根据自己需求返回用户唯一身份return httpContext.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;};...});

  • [RateValve(Policy = Policy.Header, PolicyKey = "hkey", Limit = 1, Duration = 30, WhenNull = WhenNull.Intercept)]

    代表根据Request Header中hkey对应的值,每30秒可访问1次该接口。如果无法取得Header中的值或取得的值为空,则进行拦截。

    关于WhenNull:

    WhenNull = WhenNull.Pass:对应策略取得的识别值为空时,不进行拦截。

    WhenNull = WhenNull.Intercept:对应策略取得的识别值为空时,进行拦截。

  • [RateValve(Policy = Policy.Query, PolicyKey = "mobile", Limit = 1, Duration = 30, WhenNull = WhenNull.Pass)]

    代表根据Request Query中mobile对应的值,每30秒可访问1次该接口。如果无法取得识别值或取得的值为空,则不进行拦截。

  • [BlackListValve(Policy = Policy.Query, PolicyKey = "mobile")]

    黑名单拦截,代表根据Request Query中mobile对应的值,如果在黑名单中,则进行拦截。关于如何添加黑名单,请参照后面关于IApiThrottleService部分。

  • [WhiteListValve(Policy = Policy.Ip)]

    白名单拦截,代表根据客户端IP地址,如果在白名单中,则不进行拦截(如果同一个Api上有多个Valve,按序当检查到白名单符合时,则代表检查通过,不进行后续Valve的拦截检查)。关于如何添加白名单,请参照后面关于IApiThrottleService部分。

  • 一个Api多个Valve

        // POST api/values
        [HttpPost][WhiteListValve(Policy = Policy.Ip, Priority = 3)][BlackListValve(Policy = Policy.UserIdentity, Priority = 2)][RateValve(Policy = Policy.Header, PolicyKey = "hkey", Limit = 1, Duration = 30, WhenNull = WhenNull.Pass)]public void Post([FromBody] string value){}

    多个Valve根据Priority值从大到小进行拦截,如果被拦截,则不进行后续Valve拦截检查。

全局限流配置

以上都是对单个Api进行限流管理的,如果需要对全局进行限流管理,可在`Startup.cs`中进行如下配置:
       //Api限流services.AddApiThrottle(options => {...options.Global.AddValves(new BlackListValve{Policy = Policy.Ip,Priority = 99}, new WhiteListValve{Policy = Policy.UserIdentity,Priority = 88},new BlackListValve{Policy = Policy.Header,PolicyKey = "throttle"}, new RateValve{Policy = Policy.Ip,Limit = 5,Duration = 10,WhenNull = WhenNull.Pass});...});

以上代表给全局添加了4个Valve进行拦截,如果被拦截,则不进行后续操作。白名单检查通过时,代表全局拦截通过,不进行后续全局Valve检查(后续单独Api的检查还会进行)。相同识别策略(Policy+PolicyKey)的Valve只能添加一个,重复不会添加。全局限流拦截在Middlewarez中进行,单独Api限流拦截在IAsyncActionFilter中进行,当然也支持Razor Page,在IAsyncPageFilterz中进行限流。

其他自定义配置项

  • 自定义IP地址取得方法:

    //Api限流services.AddApiThrottle(options => {...//以下是 Dnc.Api.Throttle 默认取得Ip地址的方法,可进行自定义options.OnIpAddress = (context) => {var ip = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();if (string.IsNullOrEmpty(ip)){ip = context.Connection.RemoteIpAddress.ToString();}return ip;};...});

  • 自定义拦截后处理:

           //Api限流services.AddApiThrottle(options => {...options.onIntercepted = (context, valve, where) =>{//valve:引发拦截的valve//where:拦截发生的地方,有ActionFilter,PageFilter,Middleware(全局)if (where == IntercepteWhere.Middleware){//注意:Middleware中返回的ActionResult无法在ResultFilter中拦截处理。return new JsonResult(new { code = 99, message = "访问过于频繁,请稍后重试!" });}else{return new ApiThrottleResult { Content = "访问过于频繁,请稍后重试!" };}};...});

    IApiThrottleService

    使用IApiThrottleService接口可实现黑名单、白名单的管理维护等其他功能。

    使用范例:

        /// <summary>/// Api限流管理服务/// </summary>private readonly IApiThrottleService _service;public ValuesController(IApiThrottleService service){_service = service;}[HttpPost][BlackListValve(Policy = Policy.Ip)]public async Task AddBlackList(){var ip = GetIpAddress(HttpContext);//添加IP黑名单await _service.AddRosterAsync(RosterType.BlackList, "WebApiTest.Controllers.ValuesController.AddBlackList", Policy.Ip, null, TimeSpan.FromSeconds(60), ip);}/// <summary>/// 取得客户端IP地址/// </summary>private static string GetIpAddress(HttpContext context){var ip = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();if (string.IsNullOrEmpty(ip)){ip = context.Connection.RemoteIpAddress.ToString();}return ip;}

    AddBlackList中针对WebApiTest.Controllers.ValuesController.AddBlackList方法添加了一个有效期60的IP黑名单,当前IP调用该接口会被IP黑名单拦截。
    
    
    IApiThrottleService 现有接口:
        #region 黑名单 & 白名单/// <summary>/// 添加名单/// </summary>/// <param name="rosterType">名单类型</param>/// <param name="api">Api</param>/// <param name="policy">策略</param>/// <param name="policyKey">策略Key</param>/// <param name="expiry">过期时间</param>/// <param name="item">项目</param>Task AddRosterAsync(RosterType rosterType, string api, Policy policy, string policyKey, TimeSpan? expiry, params string[] item);/// <summary>/// 删除名单中数据/// </summary>/// <param name="rosterType">名单类型</param>/// <param name="api">API</param>/// <param name="policy">策略</param>/// <param name="policyKey">策略Key</param>/// <param name="expiry">过期时间</param>/// <param name="item">项目</param>Task RemoveRosterAsync(RosterType rosterType, string api, Policy policy, string policyKey, params string[] item);/// <summary>/// 取得名单列表(分页)/// </summary>/// <param name="rosterType">名单类型</param>/// <param name="api">API</param>/// <param name="policy">策略</param>/// <param name="policyKey">策略Key</param>Task<(long count, IEnumerable<ListItem> items)> GetRosterListAsync(RosterType rosterType, string api, Policy policy, string policyKey, long skip, long take);/// <summary>/// 取得名单列表/// </summary>/// <param name="rosterType">名单类型</param>/// <param name="api">API</param>/// <param name="policy">策略</param>/// <param name="policyKey">策略Key</param>Task<IEnumerable<ListItem>> GetRosterListAsync(RosterType rosterType, string api, Policy policy, string policyKey);/// <summary>/// 添加全局名单/// </summary>/// <param name="rosterType">名单类型</param>/// <param name="policy">策略</param>/// <param name="policyKey">策略Key</param>/// <param name="expiry">过期时间</param>/// <param name="item">项目</param>Task AddGlobalRosterAsync(RosterType rosterType, Policy policy, string policyKey, TimeSpan? expiry, params string[] item);/// <summary>/// 移除全局名单/// </summary>/// <param name="policy">策略</param>/// <param name="item">项目</param>Task RemoveGlobalRosterAsync(RosterType rosterType, Policy policy, string policyKey, params string[] item);/// <summary>/// 取得全局名单列表(分页)/// </summary>/// <param name="rosterType">名单类型</param>/// <param name="policy">策略</param>/// <param name="policyKey">策略Key</param>Task<(long count, IEnumerable<ListItem> items)> GetGlobalRosterListAsync(RosterType rosterType, Policy policy, string policyKey, long skip, long take);/// <summary>/// 取得全局名单列表/// </summary>/// <param name="rosterType">名单类型</param>/// <param name="policy">策略</param>/// <param name="policyKey">策略Key</param>Task<IEnumerable<ListItem>> GetGlobalRosterListAsync(RosterType rosterType, Policy policy, string policyKey);#endregion

    Github:https://github.com/kulend/Dnc.Api.ThrottleNuGet:https://www.nuget.org/packages/Dnc.Api.Throttle
    
     

转载于:https://www.cnblogs.com/kulend/p/9435095.html

【Dnc.Api.Throttle】适用于.Net Core WebApi接口限流框架相关推荐

  1. redis rua解决库存问题_库存秒杀问题-redis解决方案- 接口限流

    /** * Created by PhpStorm. * redis 销量超卖秒杀解决方案 * redis 文档:http://doc.redisfans.com/ * ab -n 10000 -c ...

  2. 【限流02】限流算法实战篇 - 手撸一个单机版Http接口通用限流框架

    本文将从需求的背景.需求分析.框架设计.框架实现几个层面一步一步去实现一个单机版的Http接口通用限流框架. 一.限流框架分析 1.需求背景 微服务系统中,我们开发的接口可能会提供给很多不同的系统去调 ...

  3. 用令牌桶算法完成API接口限流

    这是张富涛的第15篇原创 用令牌桶算法完成API接口限流 本文介绍了"令牌桶算法",和使用lua+redis实现基于令牌桶算法的限流. 1. 限流需求的产生背景 软件开发时偶尔会面 ...

  4. 接口限流算法:漏桶算法amp;令牌桶算法

    转载自 接口限流算法:漏桶算法&令牌桶算法 背景 每一个对外提供的API接口都是需要做流量控制的,不然会导致系统直接崩溃.很简单的例子,和保险丝的原理一样,如果用电符合超载就会烧断保险丝断掉电 ...

  5. Hystrix面试 - 深入 Hystrix 线程池隔离与接口限流

    Hystrix面试 - 深入 Hystrix 线程池隔离与接口限流 前面讲了 Hystrix 的 request cache 请求缓存.fallback 优雅降级.circuit breaker 断路 ...

  6. 接口限流算法及解决方案

    参考: 接口限流算法:漏桶算法&令牌桶算法 文章目录 一.限流算法 1. 漏桶算法 2. 令牌桶算法 二.令牌桶算法VS漏桶算法 三.解决方案 1. 使用Guava的RateLimiter进行 ...

  7. 接口限流:限制接口的访问频率

    限流,顾名思义,就是限制对 API 的调用频率.每一次 API 调用,都要花费服务器的资源,因此很多 API 不会对用户无限次地开放,请求达到某个次数后就不再允许访问了,或者一段时间内,最多只允许访问 ...

  8. 使用令牌桶算法解决调用第三方接口限流问题

    我们在调用第三方接口时常常会碰到接口限流问题,为了解决这一问题,大家想出了许多方法.我这里介绍一下我的方法,第三方接口限流一般是基于令牌桶算法的,那么我们可以以彼之道还治彼身,使用令牌桶算法实现我方调 ...

  9. php接口限流实现方法

    因为现在动不动就说高并发,说到高并发 就不得不提并发下限流.熔断.降级. 为什么要进行接口限流呢? 个人认为其实目的都是为了保证线上系统的稳定性,防止因为高频访问服务器而导致服务器宕机. 下面来简单实 ...

最新文章

  1. java拦截到登陆界面,JavaWeb 使用Filter实现自动登录
  2. hbase或hadoop错误及解决方法
  3. 网站优化有什么值得注意的小细节吗?
  4. jsonutil java_Java实现的JSONUtil工具类与用法示例
  5. 如何让电脑成为看图说话的高手?计算机视觉顶会ICCV论文解读
  6. 1054. 距离相等的条形码
  7. LuckyDraw bot有幸被提名为微软2019的People's Choice app
  8. 基于Passthru的NDIS开发的个人理解
  9. SSH (Secure Shell)详解
  10. 脚注交叉引用序号不一样_利用Word的尾注来做参考文献的注释编号--解决编号加方括号,交叉引用,去除尾注上访横线等问题...
  11. oracle 12c 备份pdb下数据库
  12. java demo类_《java语言程序设计》初步学习——各种小Demo
  13. mysql二进制文件如何查看_使用mysqlbinlog查看MySQL二进制文件内容
  14. AOD实践,modis数据下载,modis数据处理,
  15. windows10补丁包离线更新
  16. python中的写入文件
  17. 苹果App Store应用程序的下载链接地址
  18. Qt自定义控件大全文章导航
  19. Tik Tok月活12亿 Tiktok和抖音有什么不同 ?
  20. 2021年全球医药电子商务行业调研及趋势分析报告

热门文章

  1. 2018年江苏省监理工程师考试软件练习题库模拟测试免费下载注册机码监理工程师教材2018江苏省监理人员业务培训教程习题集模拟考自测
  2. android11.0去掉锁屏和设置里充电剩余时间
  3. 使用ESP8266播放音乐
  4. 你真的会写测试用例吗?如何写?测试用例之中的细节拉满了...
  5. 第四章——Web镇之旅:连接起来
  6. Unity NavMesh蓝色表面不出现
  7. Android从1.0到 6.0各版本的差别
  8. 游戏的云时代何时能到?
  9. Flask框架——路由:URL规则与视图函数
  10. C#实现微秒(us)级延时