FireflySoft.RateLimit 使用

限流处理器

使用FireflySoft.RateLimit首先需要创建一个限流处理器RateLimitProcessor的实例,然后用它来过滤每一个请求。创建RateLimitProcessor的实例,至少需要提供两个信息:被限流的请求类型、限流算法和规则。其它还有限流计数持久化方式、限流错误信息,如果不提供会使用默认值。这里先不展开,后边会详细介绍它们。创建RateLimitProcessor需要采用构造器模式,如果你使用ASP.NET Core应该很熟悉,如果没什么印象打开Program.cs就可以看到了。为了提高效率,这个限流处理器一般会统一放在某个过滤器中,这个过滤器在ASP.NET中可以是一个消息处理器,在ASP.NET Core中一般就是一个中间件。为了方便集成,FireflySoft.RateLimit已经提供了一个基于ASP.NET的消息处理器和一个基于ASP.NET Core的中间件,通过Github和Nuget都可以很方便的找到他们,Github上还提供了演示程序.

被限流请求类型

被限流请求类型就是需要被限制的业务请求的类型,在ASP.NET中他可能是HttpRequestMessage,在ASP.NET Core中它可能是HttpContext,在其它业务中它可能是你自定义的一个类型XXXRequest。被限流请求类型很重要,因为不同的业务可能使用不同的请求类型,而限流处理程序需要从当前请求中提取或关联到限流目标,明确请求类型才能确定提取方法,否则对请求进行限制将无所适从

限流算法和规则

FireflySoft.RateLimit提供了四种常见的限流算法:固定窗口、滑动窗口、漏桶、令牌桶。固定窗口相对最简单,无论是算法的时间复杂度还是分布式环境实现难度都比较有优势,如果需求是在较短的时间内进行限制,比如每秒限制多少次,使用这种算法是最合适的。但是实际场景中请求在时间分布中可能不太均匀,时多时少,根据需求的不同,可能需要选择其它三种限流算法,这里不做说明了,网上已经有很多的场景选择说明。 初始化限流算法还需要提供对应的限流规则,因为不同的算法往往需要不同的参数,这里很难对不同的算法提供完全统一的限流规则,不过这些规则确实是有共同设置项的,比如限流锁定时间、目标提取方法、是否应用限流处理的判断方法等。 以上文【使用方法】中的限流代码为例,做一些介绍:

  1. FixedWindowAlgorithm是此限流组件提供的固定窗口限流算法。

  2. FixedWindowRateLimitRule是此限流组件提供的固定窗口限流规则类型;

  3. HttpContext是业务中需要限制的请求类型,这里是Http请求上下文类型;

  4. StatWindow是固定窗口的大小,是一个时间跨度;

  5. LimitNumber是限流值,在StatWindow时间内请求数超过它就会触发限流;

  6. LockSeconds是触发限流后的锁定时间,此时间内请求都会被阻止,不需要锁定时可以不设置;

  7. ExtractTarget传递一个方法用于从请求中提取限流目标,这里是用户的每一个请求路径;

  8. CheckRuleMatching传递一个方法用于检查当前请求是否需要限流检查,这里return true代表所有请求都要经过限流检查。

这里有两个比较有意思的设置:ExtractTargetCheckRuleMatching,他们共同作用,让用户可以完全自由的定制自己限流的目标和条件,不固定是IP、ClientId或者Url。其它算法规则中每个设置项的含义可以通过其注释了解到。 如果这几个算法还不能满足要求,可以通过实现IRateLimitAlgorithm来定义一个新的算法。

计数持久化方式

FireflySoft.RateLimit中的限流计数目前支持保存在内存或者Redis中,也可以通过实现IRateLimitStorage来定义一个新的存储器。 对于只需要部署一份的程序,绝大部分情况下使用内存就够了;但是如果限流的时间窗口比较长,比如1小时限制300次,重启就会丢失计数,这可能是个风险,此时使用Redis会比较合适。 对于需要部署多份的程序,如果请求是基本均匀的,并且在每个部署之间的分配也是均匀的,那么使用内存存储器也未尝不可,将总的限流数平均分配在每一个部署中,只要有一个部署触发限流,其它部署很大几率上也会触发限流。但是对于需要部署多份的情况,采用更持久的Redis方式才是稳妥的。 相比内存访问,Redis访问需要网络交互,这会造成一定的性能损失,访问量很大时也会产生拥堵,不过也可以将请求分散到多个Redis的方式进行缓解;同时分布式环境下数据一致性的实现难度更大,即使使用Redis,比如限流处理中必然会涉及的各种时间,不同节点之间的时间不可能绝对一致,越短的时间窗口协调难度越大。因此使用滑动窗口、漏桶、令牌桶等分布式实现难度较大的算法时,需要注意时间单位的设置.

限流错误信息

限流错误信息是触发限流时限流检查结果中附带的信息,目前每个限流处理器允许设置一个统一的RateLimitError,方便业务侧进行统一处理。默认限流错误Code是429,Message为null。你也可以不使用这个定义的值,根据当前限流目标和限流规则构造自己的错误信息

限流锁定

限流锁定是触发限流时的惩罚性处理。FireflySoft.RateLimit通过设置限流规则中的LockSeconds,定义触发限流后的锁定时间,此时间内的请求都会被认定触发限流规则,而不被允许通过;如果不需要锁定忽略这个设置就可以了

如上图所示,时间单位是1秒,阈值是3。

  • 第1秒3个请求,不会触发限流;

  • 第2秒1个请求,不会触发限流;

  • 第3秒4个请求,这一秒的前3个请求正常处理,第4个请求触发限流,会被拒绝处理。

  • 后续第4秒、第5秒不会触发限流,所有请求正常处理。

Core、AspNet、Middleware 3种

Github 源码地址

GitHub - bosima/FireflySoft.RateLimit: It is a rate limiting library based on .Net standard.

ProjectDescriptioin
FireflySoft.RateLmit.CoreFireflySoft.RateLmit的算法、规则、持久化和其它核心代码。
FireflySoft.RateLimit.AspNet为基于 .NET Framework的ASP.NET提供的限流组件。
FireflySoft.RateLimit.AspNetCoreASP.NET Core限流中间件。
FireflySoft.RateLimit.Core.UnitTestUnit test for FireflySoft.RateLimit.Core.
FireflySoft.RateLimit.Core.BenchmarkTestBenchmark test for FireflySoft.RateLimit.Core.
samples/consoleFireflySoft.RateLmit.Core sample program.
samples/aspnetFireflySoft.RateLimit.AspNet sample program.
samples/aspnetcoreFireflySoft.RateLimit.AspNetCore sample program.
samples/aspnetcore6FireflySoft.RateLimit.AspNetCore with .NET6 sample program.

ASP.NET Core 使用方法:

1、Install Nuget Package Package Manager: Install-Package FireflySoft.RateLimit.AspNetCore Or .NET CLI: dotnet add package FireflySoft.RateLimit.AspNetCore

Use Middleware 使用方法:

public void ConfigureServices(IServiceCollection services) { ...

services.AddRateLimit(new InProcessFixedWindowAlgorithm(
    new[] {
        new FixedWindowRule()
        {
            ExtractTarget = context =>
            {
                return (context as HttpContext).Request.Path.Value;
            },
            CheckRuleMatching = context =>
            {
                return true;
            },
            Name="default limit rule",
            LimitNumber=30,
            StatWindow=TimeSpan.FromSeconds(1)
        }
    })
);
​
...

}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { ...

app.UseRateLimit();
​
...

}

ASP.NET

1、Install Nuget Package:

Install-Package FireflySoft.RateLimit.AspNet

2、Register MessageHandler

Open Global.asax.cs, the following code adds the rate limit message handle:

protected void Application_Start() { ...

GlobalConfiguration.Configuration.MessageHandlers.Add(
    new RateLimitHandler(
        new Core.InProcessAlgorithm.InProcessFixedWindowAlgorithm(
            new[] {
                new FixedWindowRule()
                {
                    ExtractTarget = context =>
                    {
                        return (context as HttpRequestMessage).RequestUri.AbsolutePath;
                    },
                    CheckRuleMatching = context =>
                    {
                        return true;
                    },
                    Name="default limit rule",
                    LimitNumber=30,
                    StatWindow=TimeSpan.FromSeconds(1)
                }
            })
    ));
​
...

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值