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 ,只不过需要自己处理限流结果。

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

到此这篇关于ASP.NET Core中使用令牌桶限流的实现的文章就介绍到这了,更多相关ASP.NET Core中使用令牌桶限流内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Asp.NET Core 限流控制(AspNetCoreRateLimit)的实现

    起因: 近期项目中,提供了一些调用频率较高的api接口,需要保障服务器的稳定运行:需要对提供的接口进行限流控制.避免因客户端频繁的请求导致服务器的压力. 一.AspNetCoreRateLimit 介绍 AspNetCoreRateLimit 是一个ASP.NET Core速率限制的解决方案,旨在控制客户端根据IP地址或客户端ID向Web API或MVC应用发出的请求的速率.AspNetCoreRateLimit包含一个 IpRateLimitMiddleware 和 ClientRateLim

  • ASP.NET Core对不同类型的用户进行区别限流详解

    前言 老板提出了一个新需求,从某某天起,免费用户每天只能查询100次,收费用户100W次. 这是一个限流问题,聪明的你也一定想到了如何去做:记录用户每一天的查询次数,然后根据当前用户的类型使用不同的数字做比较,超过指定的数字就返回错误. 嗯,原理就是这么简单.不过真正写起来还要考虑更多问题: 统计数据的数据结构是什么样的?字典 or 行记录? 统计数据记录到哪里?内存 or MySQL or Redis? 分布式应用怎么精确计数?分布式锁 or 队列 or 事务? 吞吐量比较大时如何扛得住?内存

  • ASP.NET Core中使用令牌桶限流的实现

    在限流时一般会限制每秒或每分钟的请求数,简单点一般会采用计数器算法,这种算法实现相对简单,也很高效,但是无法应对瞬时的突发流量. 比如限流每秒100次请求,绝大多数的时间里都不会超过这个数,但是偶尔某一秒钟会达到120次请求,接着很快又会恢复正常,假设这种突发的流量不会对系统稳定性带来实质性的影响,则可以在一定程度上允许这种瞬时的突发流量,从而为用户带来更好的可用性体验.这就是令牌桶算法的用武之地. 该算法的基本原理是:有一个令牌桶,容量是X,每Y单位时间会向桶中放入Z个令牌,如果桶中的令牌数超

  • ASP.NET Core中使用滑动窗口限流的问题及场景分析

    目录 算法原理 漏检 太刚 算法实现 进程内即内存滑动窗口算法 基于Redis的滑动窗口算法 应用算法 1.安装Nuget包 2.使用中间件 滑动窗口算法用于应对请求在时间周期中分布不均匀的情况,能够更精确的应对流量变化,比较著名的应用场景就是TCP协议的流量控制,不过今天要说的是服务限流场景中的应用. 算法原理 这里假设业务需要每秒钟限流100次,先来看固定窗口算法的两个问题: 漏检 如下图所示,单看第1秒和第2秒,其请求次数都没有超过100,所以使用固定窗口算法时不会触发限流.但是第1秒的后

  • 浅析Spring Cloud Gateway中的令牌桶限流算法

    目录 前言 回顾限流算法 计数器/时间窗口法 漏桶法 令牌桶法 主要逻辑分析 前言 在一个分布式高并发的系统设计中,限流是一个不可忽视的功能点.如果不对系统进行有效的流量访问限制,在双十一和抢票这种流量洪峰的场景下,很容易就会把我们的系统打垮.而作为系统服务的卫兵的网关组件,作为系统服务的统一入口,更需要考虑流量的限制,直接在网关层阻断流量比在各个系统中实现更合适.Spring Cloud Gateway的实现中,就提供了限流的功能,下面主要分析下Spring Cloud Gateway中是如何

  • 解决ASP.NET Core中使用漏桶算法限流的问题

    目录 算法原理 算法实现 进程内即内存漏桶算法 基于Redis的漏桶算法 应用算法 1.安装Nuget包 2.使用中间件 漏桶算法是限流的四大主流算法之一,其应用场景各种资料中介绍的不多,一般都是说应用在网络流量控制中.这里举两个例子: 1.目前家庭上网都会限制一个固定的带宽,比如100M.200M等,一栋楼有很多的用户,那么运营商怎么保证某些用户没有使用过多的带宽,从而影响到别人呢?这时就可以使用漏桶算法,限制每个用户访问网络的最大带宽,当然实际会比这复杂很多. 2.有一个祖传接口,当时写的时

  • ASP.NET Core基于滑动窗口实现限流控制

    目录 前言: 二.固定窗口算法 三.滑动窗口算法 四.实现 六.使用 结论: 前言: 在实际项目中,为了保障服务器的稳定运行,需要对接口的可访问频次进行限流控制,避免因客户端频繁请求导致服务器压力过大. 而​AspNetCoreRateLimit是目前ASP.NET Core下最常用的限流解决方案. 查看它的实现代码,我发现它使用的固定窗口算法. var entry = await _counterStore.GetAsync(counterId, cancellationToken); if

  • 浅谈ASP.NET Core 中jwt授权认证的流程原理

    1,快速实现授权验证 什么是 JWT ?为什么要用 JWT ?JWT 的组成? 这些百度可以直接找到,这里不再赘述. 实际上,只需要知道 JWT 认证模式是使用一段 Token 作为认证依据的手段. 我们看一下 Postman 设置 Token 的位置. 那么,如何使用 C# 的 HttpClient 访问一个 JWT 认证的 WebAPI 呢? 下面来创建一个 ASP.NET Core 项目,尝试添加 JWT 验证功能. 1.1 添加 JWT 服务配置 在 Startup.cs 的 Confi

  • 详解ASP.NET Core中配置监听URLs的五种方式

    默认情况下,ASP. NET Core应用会监听一下2个Url: http://localhost:5000 https://localhost:5001 在本篇博文中,我将展示如何使用五种不同的方式改变应用监听的URLs. 在ASP.NET Core项目启动时,有多种配置监听Url的方式,在我之前的一篇博客中,已经展示了在ASP.NET Core 1.0中如何应用不同的方式配置,在ASP.NET Core 3.x中,大部分方式还是一样的. UseUrls() - 在Program.cs配置程序

  • ASP.NET Core中HttpContext详解与使用

    “传导体” HttpContext 要理解 HttpContext 是干嘛的,首先,看图 图一 内网访问程序 图二 反向代理访问程序 ASP.NET Core 程序中,Kestrel 是一个基于 libuv 的跨平台ASP.NET Core web服务器.不清楚 Kerstrel 没关系,以后慢慢了解. 我们可以理解成,外部访问我们的程序,通过 Http 或者 Https 访问,例如https://localhost:44337/Home/Index,需要通过一个网址,来寻向访问特定的页面. 访

  • ASP.NET Core中的策略授权和ABP授权

    目录 ASP.NETCore中的策略授权 策略 定义一个Controller 设定权限 定义策略 存储用户信息 标记访问权限 认证:Token凭据 颁发登录凭据 自定义授权 IAuthorizationService ABP授权 创建ABP应用 定义权限 ASP.NET Core 中的策略授权 首先我们来创建一个 WebAPI 应用. 然后引入 Microsoft.AspNetCore.Authentication.JwtBearer 包. 策略 Startup 类的 ConfigureServ

  • 在 ASP.NET Core 中使用 HTTP 标头传播详情

    目录 前言 Demo 结论 前言 我们常用 JWT 令牌用于身份验证,前端一般是在请求中包含 HTTP 标头 Authorization 实现. 但是,当服务间需要互相调用时,也需要"按原样"将标头传播到目标服务. 原来的解决方案是从请求中读取标头,并将其添加到对外请求标头集合中. 后来发现,微软已经考虑了这种场景,并提供了专门的中间件来解决这个需求. Demo 下面,我们创建 ServerA.ServiceB 两个 Web API 项目来演示这一功能. 首先,ServiceB 有一个

随机推荐