首页 > 编程语言 >ASP.NET Core-限流(Rate Limiting)

ASP.NET Core-限流(Rate Limiting)

时间:2023-12-21 16:44:58浏览次数:39  
标签:Core 令牌 ASP 窗口 请求 限流 滑动 100

一、应用场景

       微服务架构中,限流功能一般由网关提供。而对于很多非微服务化的系统,可能并没有网关[无论是因为成本还是复杂度],在这种场景下,为了实现限流,.NET 7中提供了限流中间件 Rate Liniting。

二、实现

       首先,SDK版本 >= 7。

       然后添加代码注册。

       微软为我们提供了4中常用的限流算法:

  1. 固定窗口限流器【FixedWindowLimiter
  2. 滑动窗口限流器【SlidingWindowLimiter
  3. 令牌桶限流器【TokenBucketLimiter
  4. 并发限流器【ConcurrencyLimiter

      通常我们会注册一个命名限流策略,并在该策略内指定限流算法,以及其他限流逻辑。需要注意的是,UseRateLimiter的位置,若限流行为作用于特定路由,这限流中间件必须放到UseRouting之后。

三、详情

       3.1、固定窗口限流器

                固定窗口限流器比较简单,限流方式如下:

                【原理】:使用固定的时间长度来限制请求数量。如固定窗口长度为10s,则每10s就会切换(销毁并创建)一个新窗口,在每个单独的窗口内,限制请求数量。

                 【特点】:

                               优点:实现简单,内存占用低。

                               缺点:

                                         1、当窗口QPS到达阈值,流量会被瞬间切断,不能平滑处理突发流量(实际应用中理想效果是让流量平滑的进入系统)

                                         2、窗口切换时可能出现2倍QPS。如窗口大小为1s,阈值为100,窗口1在后500ms内处理100个请求,窗口2在前500ms内也处理100个请求,这样就导致实际在1s内处理了200个请求。 

 

          

#region 注册限流中间件

builder.Services.AddRateLimiter(options =>
{
    //1、固定窗口限流策略
    //配置说明:该固定窗口60s时间内,可以最多有100+50=150个请求,100个会被处理,50个会被排队,其他则会在一定时间后拒绝返回 RejectionStatusCode
    options.AddFixedWindowLimiter(policyName:"fixed",fixedOptions =>
    {
        fixedOptions.PermitLimit = 100;//每个窗口时间范围内,允许100个请求被处理
        fixedOptions.Window = TimeSpan.FromSeconds(60); //窗口大小。即窗口时间长度60s。必须>TimeSpan.Zero
        fixedOptions.QueueLimit = 50;//窗口阈值。即每个窗口时间范围内,最多允许的请求个数。该值必须>0。当窗口请求达到最大值,后续请求会进入排队。该值用于设置对垒大小(即允许几个请求在排队队列等待)
        fixedOptions.QueueProcessingOrder = System.Threading.RateLimiting.QueueProcessingOrder.OldestFirst;//排队请求的处理顺序。这里设置为有限处理先来的请求
        fixedOptions.AutoReplenishment = true;//开启新窗口时是否自动重置请求限制,默认true。如果是false,则需要手动调佣 FixedWindowRateLimiter.TryReplenish来重置
    });
});

#endregion

//使用限流器
app.UseRateLimiter();
View Code

       3.2、滑动窗口限流器

               滑动窗口限流器是固定窗口限流器的升级版。

                【原理】:在固定窗口限流器的基础上,它将每个窗口划分为多个段,每经过一个段的时间间隔(=窗口时间/窗口段的个数),窗口就会向后滑动一段,所以称为滑动窗口(窗口大小仍是固定的)。当窗口滑动后,会“吃进”一个段(称为当前段),并“吐出”一个段(称为过期端),过期段会被回收,回收的请求数可以用于当前段。

                【特点】:

                                优点:按段滑动处理,相对于固定窗口,可以对流量进行更精准的控制,更平滑的处理突发流量,并且段划分的越多,移动更平滑。

                                缺点:对时间精度要求高,比固定窗口实现复杂,占用内存更高。

 

//2、滑动窗口限流则略
//配置说明:窗口时间长度为30s,每个窗口内,最多允许100个请求,窗口段数3,每个段的时间间隔为30/3=10s,即窗口每10s滑动一段。
options.AddSlidingWindowLimiter(policyName:"sliding", slidingOptions =>
{
    slidingOptions.PermitLimit = 100;
    slidingOptions.Window = TimeSpan.FromSeconds(30);
    slidingOptions.QueueLimit = 2;
    slidingOptions.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
    slidingOptions.AutoReplenishment = true;//开启新窗口时是否自动重置请求限制,默认true
    slidingOptions.SegmentsPerWindow = 3;
});
View Code

 

                【理解】:滑动窗口就是为了解决固定窗口2n的问题。

                                  计算公式:估计数 = 前一窗口技术 * (1 - 当前窗口经过时间/单位时间)+ 当前窗口计数

                                  举个例子:窗口为每分钟最大处理10个请求。这实际计算后数据为:估计数=9 * (1-25%) + 5 = 11.75 > 10,则最后的一次请求会被阻止。虽然在单个窗口内,请求数都没有超过最大限制,但是超过了加权计算结果。                               

                              另外,滑动窗口的段,可以理解为每次加权计算移动的时间距离。如果最近的2次请求相距两个时间窗口,则可以认为前一窗口计数为零,重新开始计数。

 

       3.3、令牌桶限流器

                 令牌桶限流器是一种限制数据平均传输速率的限流算法。

                 【原理】:想象有一个桶,每个固定时间段会向桶内放入固定数量的令牌(token),当桶内令牌装满时,新的令牌将会被丢弃。当请求流量进入时,会先从桶内拿 1 个令牌,拿到了则该请求会被处理,没拿到则会在队列中等待,若队列已满,则会被限流拒绝处理。

                  【特点】:可以限制数据的平均传输速率,还可以一次性耗尽令牌应对突发流量,并平滑地处理后续流量,是一种通用的算法。

 

             

//策略说明:桶最多装4个令牌,每10秒发放一次令牌,每次发放2个令牌,所以在一个发放周期,最多可以处理4个请求,至少可以处理2个请求。
options.AddTokenBucketLimiter(policyName:"token_bucket", tokenBucketOptions =>
{
    tokenBucketOptions.TokenLimit = 4;//桶最多可以装的令牌数,发放的多余令牌会被丢弃
    tokenBucketOptions.ReplenishmentPeriod = TimeSpan.FromSeconds(10);//令牌发放周期
    tokenBucketOptions.TokensPerPeriod = 2;//每个周期发放令牌数
    tokenBucketOptions.QueueLimit = 2;//当桶内的令牌全部被拿完(token=0)时,后续请求会进入排队
    tokenBucketOptions.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
    tokenBucketOptions.AutoReplenishment = true;//进入新令牌发放周期,是否自动发放令牌。如果设置为false,则需要手动调用 TokenBucketRateLimiter.TryReplenish来发放
});
View Code

 

       3.4、并发限流器

               并发限流器不是限制一段时间内的最大请求数,而是限制并发数。

               【原理】:限制同一时刻并发请求的数量。

               【特点】:可以充分利用服务器的性能,当出现突发流量时,服务器负载可能会持续过高。

 

//策略说明:最大并发请求4,超过最大并发请求,则后续最多2个请求进入排队队列。
options.AddConcurrencyLimiter(policyName:"concurrency", concurrencyOptions =>
{
    concurrencyOptions.PermitLimit = 4;//最大并发请求数
    concurrencyOptions.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
    concurrencyOptions.QueueLimit = 2;//当并发请求数达到最大,后续请求进入排队,该参数用于配置队列大小
});
View Code

 

标签:Core,令牌,ASP,窗口,请求,限流,滑动,100
From: https://www.cnblogs.com/xiaobaicai12138/p/17918987.html

相关文章

  • POI中创建条件格式后使用aspose转换为PDF时,颜色不正常的问题
    场景:使用一个EXCEL模板,其中创建了一些条件格式,通过EASYPOI进行模板填充,使用FE模板指令,复制填充了一些行,同时复制了这些行中存在的条件格式。现象:打开EXCEL,条件格式是正常的,但是随后通过ASPOSECELLS将XLSX转换为PDF,会发现新创建的条件格式的长短、颜色都不正常解决方法一:在EXCE......
  • 分类模型评估(混淆矩阵, precision, recall, f1-score)的原理和Python实现
    混淆矩阵当我们已经获取到一个分类模型的预测值,可以通过不同指标来进行评估。往往衡量二分类模型是基于以下的混淆矩阵概念:TruePositive:真实值为正、预测值为正(真阳性)FalsePositive:真实值为负、预测值为正(假阳性)FalseNegative:真实值为正、预测值为负(假阴性)TrueNegative......
  • QLabel显示图片,QPixmap.scaled Qt::KeepAspectRatio不起作用
    一、问题描述以及解决办法Qt中QLabel可以显示图片。如下:QLabel*label=newQLabel(this);label->setPixmap(QPixmap)其中QPixmap可以缩放图片Pixmappixmap;pixmap.scaled(QSize(width,height),Qt::KeepAspectRatio);//按比例缩放以适应目标矩形,超出部分会被裁......
  • SpringBoot中使用Aspect实现切面
    相关概念切面(Aspect):首先要理解‘切’字,需要把对象想象成一个立方体,传统的面向对象变成思维,类定义完成之后(封装)。每次实例化一个对象,对类定义中的成员变量赋值,就相当于对这个立方体进行了一个定义,定义完成之后,就等着被使用,等着被回收。面向切面编程则是指,对于一个我们已经封装......
  • Owasp Top10 漏洞解析 之注入
    一、注入漏洞是什么?注入漏洞,即将不受信任的数据作为命令或查询的一部分发送到解析器时,会产生诸如SQL注入NoSQL注入、OS注入和LDAP注入的注入缺陷。攻击者的恶意数据可以诱使解析器在没有适当授权的情况下执行非预期命今或访问数据。几乎任何数据源都能成为注入载体,包括环境变量......
  • 如何在 ASP.NET Core 中使用 Route 特性
    ASP.NETCore中的Route中间件的职责在于将request匹配到各自Route处理程序上,Route分两种:基于约定和基本特性模式。基于约定模式的Route采用集中化的方式,而基于特性的方式允许你在Action或者Controller上单独定义,到底采用哪一种可以基于你自己的应用场景,本篇就......
  • 【ASP】读取数据库并显示字段的值例子
    1、不循环的例子,只有一条记录<% SetRs=Server.Createobject("Adodb.Recordset") sql="selecttop1*fromRc_SFZtmkg" Rs.opensql,conn,1,1 sfzDay=rs("tmbj")'把字段值赋值给变量 Rs.Close SetRs=Nothing%>显示 <td><%=Rs("t......
  • 简便实用:在 ASP.NET Core 中实现 PDF 的加载与显示
    前言在Web应用开发中,经常需要实现PDF文件的加载和显示功能。本文小编将为您介绍如何在ASP.NETCore中实现这一功能,以便用户可以在Web应用中查看和浏览PDF文件。实现步骤1)在服务器端创建PDF打开VisualStudio并创建新的ASP.NETCoreWeb应用程序,小编这里项目名称为Create......
  • 符号执行manticore工具演练之发现缓冲区溢出漏洞
    符号执行之manticore工具演练参考资料:SANSSEC554https://docs.soliditylang.org/en/v0.8.0/ziion虚拟机:区块链智能合约中的kali(ziion涵盖演练中所以提及到的工具)动静态之分IDA是静态分析工具,常用于检测脆弱性;manticore是动态分析工具,常用于编写漏洞利用(符号执行:即执......
  • 限流、熔断、服务降级
     在分布式系统中,如果某个服务节点发生故障或者网络发生异常,都有可能导致调用方被阻塞等待,如果超时时间设置很长,调用方资源很可能被耗尽。这又导致了调用方的上游系统发生资源耗尽的情况,最终导致系统雪崩。 如果D服务发生了故障不能响应,B服务调用D时只能阻塞等待。假如......