应用算法
这里以限流组件 FireflySoft.RateLimit 为例,实现ASP.NET Core中的令牌桶算法限流。
1、安装Nuget包
有多种安装方式,选择自己喜欢的就行了。
包管理器命令:
Install-Package FireflySoft.RateLimit.AspNetCore
或者.NET命令:
dotnet add package FireflySoft.RateLimit.AspNetCore
或者项目文件直接添加:
<ItemGroup> <PackageReference Include="FireflySoft.RateLimit.AspNetCore" Version="2.*" /> </ItemGroup>
2、使用中间件
在Startup中使用中间件,演示代码如下(下边会有详细说明):
public void ConfigureServices(IServiceCollection services) { ... app.AddRateLimit(new InProcessTokenBucketAlgorithm( new[] { new TokenBucketRule(30,10,TimeSpan.FromSeconds(1)) { ExtractTarget = context => { return (context as HttpContext).Request.Path.Value; }, CheckRuleMatching = context => { return true; }, Name="default limit rule", } }) ); ... } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { ... app.UseRateLimit(); ... }
如上需要先注册服务,然后使用中间件。
注册服务的时候需要提供限流算法和对应的规则:
- 这里使用进程内令牌桶算法,对于分布式服务可以使用RedisTokenBucketAlgorithm,支持StackExchange.Redis。
- 桶的容量是30,每秒流入10个令牌。最大能够允许每秒40次请求,最少能够允许每秒10次请求,绝大部分情况下不应该超过每秒10次,可以偶尔超过10次/秒,极少数情况下达到40次/秒。
- ExtractTarget用于提取限流目标,这里是每个不同的请求Path,可以根据需求从当前请求中提取关键数据,然后设定各种限流目标。如果有IO请求,这里还支持对应的异步方法ExtractTargetAsync。
- CheckRuleMatching用于验证当前请求是否限流,传入的对象也是当前请求,方便提取关键数据进行验证。如果有IO请求,这里还支持对应的异步方法CheckRuleMatchingAsync。
- 默认被限流时会返回HttpStatusCode 429,可以在AddRateLimit时使用可选参数error自定义这个值,以及Http Header和Body中的内容。
基本的使用就是上边例子中的这些了。
如果还是基于传统的.NET Framework,则需要在Application_Start中注册一个消息处理器RateLimitHandler,算法和规则部分都是共用的,具体可以看Github上的使用说明:github.com/bosima/Fire…
FireflySoft.RateLimit 是一个基于 .NET Standard 的限流类库,其内核简单轻巧,能够灵活应对各种需求的限流场景。
其主要特点包括:
- 多种限流算法:内置固定窗口、滑动窗口、漏桶、令牌桶四种算法,还可自定义扩展。
- 多种计数存储:目前支持内存、Redis两种存储方式。
- 分布式友好:通过Redis存储支持分布式程序统一计数。
- 限流目标灵活:可以从请求中提取各种数据用于设置限流目标。
- 支持限流惩罚:可以在客户端触发限流后锁定一段时间不允许其访问。
- 动态更改规则:支持程序运行时动态更改限流规则。
- 自定义错误:可以自定义触发限流后的错误码和错误消息。
- 普适性:原则上可以满足任何需要限流的场景。
Github开源地址:github.com/bosima/Fire…