zoukankan      html  css  js  c++  java
  • ASP.NET Core中使用令牌桶限流

    在限流时一般会限制每秒或每分钟的请求数,简单点一般会采用计数器算法,这种算法实现相对简单,也很高效,但是无法应对瞬时的突发流量。

    比如限流每秒100次请求,绝大多数的时间里都不会超过这个数,但是偶尔某一秒钟会达到120次请求,接着很快又会恢复正常,假设这种突发的流量不会对系统稳定性带来实质性的影响,则可以在一定程度上允许这种瞬时的突发流量,从而为用户带来更好的可用性体验。这就是令牌桶算法的用武之地。

    如上图所示,该算法的基本原理是:有一个令牌桶,容量是X,每Y单位时间会向桶中放入Z个令牌,如果桶中的令牌数超过X,则丢弃令牌;请求要想通过首先需要从令牌桶中取出一个令牌,获取不到令牌则拒绝请求。可以看出对于令牌桶算法X、Y、Z这几个数的设定特别重要,Z应该略大于绝大数时候的Y单位时间内的请求数,系统会长期处于这个状态,X可以是系统允许承载的瞬时最大请求数,系统不能长时间处于这个状态。

    这里介绍一个ASP.NET Core的中间件来满足令牌桶限流需求:FireflySoft.RateLimit.AspNetCore。使用步骤如下:

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

    如上需要先注册服务,然后使用中间件。

    注册服务的时候需要提供限流算法和对应的规则:

    • 这里使用进程内令牌桶算法,对于分布式服务还可以使用Redis令牌桶算法,支持StackExchange.Redis。
    • 桶的容量是30,每秒流入10个令牌。
    • ExtractTarget用于提取限流目标,这里是每个不同的请求Path。如果有IO请求,这里还支持对应的异步方法ExtractTargetAsync。
    • CheckRuleMatching用于验证当前请求是否限流。如果有IO请求,这里还支持对应的异步方法CheckRuleMatchingAsync。
    • 默认被限流时会返回HttpStatusCode 429,可以在AddRateLimit时使用可选参数error自定义这个值,以及Http Header和Body中的内容。

    基本的使用就是上边例子中的这些了。


    另外这个项目也支持.Net Framework,需要安装另一个包 FireflySoft.RateLimit.AspNet,如果你的程序基于.net 4.x,可以选择这个版本。

    同时在非Web应用场景也有对应的包支持:FireflySoft.RateLimit.Core ,只不过需要自己处理限流结果。

    他们的使用方法都很类似,逻辑也很简单,都是需要先创建一个算法实例,然后通过这个实例去检查每一次请求,根据业务需要处理检查结果就可以了。

    Github开源地址:https://github.com/bosima/FireflySoft.RateLimit

  • 相关阅读:
    面试只要问到分布式,必问分布式锁
    Java编程中忽略这些细节,Bug肯定找上你
    不止承上启下,带你了解工业物联网关
    论文解读二十七:文本行识别模型的再思考
    并发高?可能是编译优化引发有序性问题
    论文解读丨LayoutLM: 面向文档理解的文本与版面预训练
    SQL优化老出错,那是你没弄明白MySQL解释计划
    SQL反模式学习笔记1 开篇
    SQL Server中自定义函数:用指定的分隔符号分割字符串
    .NET软件开发与常用工具清单
  • 原文地址:https://www.cnblogs.com/bossma/p/asp-net-core-token-bucket-algorithm-of-rate-limit.html
Copyright © 2011-2022 走看看