ASP.NET Core中使用滑动窗口限流的问题举例分析

技术ASP.NET Core中使用滑动窗口限流的问题举例分析本篇内容主要讲解“ASP.NET Core中使用滑动窗口限流的问题举例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家

本文内容主要讲解“ASP中使用滑动窗口限制电流问题的实例分析。网芯”。感兴趣的朋友不妨看看。本文介绍的方法简单、快速、实用。让边肖带你学习“ASP中使用滑动窗口限流问题的实例分析。网芯”!

滑动窗口算法用于处理时间段内请求的不均匀分布,能够更准确地处理流量变化。众所周知的应用场景是TCP协议的流量控制,但今天我们要讲的是服务限流场景中的应用。

算法原理

假设业务需要每秒限制电流100次。我们先来看看固定窗口算法的两个问题:

00-1010如下图所示,仅第1秒和第2秒的请求数不超过100,因此固定窗口算法不会触发电流限制。但前一秒最后500 ms的请求数加上第二秒前500ms的请求数超过100,此时可能会给系统带来危害,使用固定窗口算法时无法检测到这种情况。

ASP.NETCore中使用滑动窗口限流的问题举例分析

漏检

对于漏检的问题,可以说可以将时间窗口设置为500ms,将限流阈值设置为50。然后看下图,除了第二个计数周期超过50触发限流外,前一个和后一个计数周期的请求都是正常的,甚至没有超过阈值的50%。可能第二个计数周期的情况太特殊,一天之内不会出现第二次。如果不影响系统,你能适应吗?不要。固定窗口算法此时会过于死板。

ASP.NETCore中使用滑动窗口限流的问题举例分析

那么滑动窗口如何解决这两个问题呢?我们先来看看图片:

ASP.NETCore中使用滑动窗口限流的问题举例分析

如上图所示:

滑动窗口的时间跨度为1秒,每个小计数周期的时间跨度为500 ms,这里滑动窗口包含2个小计数周期。

随着时间的推移,滑动窗口中包含的小计数周期将在500ms内向前移动,但它始终包含两个小计数周期。

在判断是否限制电流时,需要将当前滑动窗口中包含的两个小计数周期的计数值相加。

与固定窗口计数算法相比,滑动窗口可以有效减少漏检。如上图所示,当滑动窗口移动到500-1500毫秒时,如果总数超过100,就会触发限流。滑动窗口不会在0-1000毫秒和1000-2000毫秒触发电流限制。即使小周期的计数值超过阈值的一半,但总数不超过100,也不会限制电流,可以应对罕见的突发流量情况。

从分析中可以看出,滑动窗口划分的小周期越多,检测越准确,但是用于跟踪的计数越多,使用的内存和计算就越多。

00-1010这里有两种实现方法:进程内内存滑动窗口算法和基于Redis的滑动窗口算法。

00-1010这里介绍一种高性能的方法,利用数组实现滑动窗口,这是循环队列的特例,如下图所示:

ASP.NETCore中使用滑动窗口限流的问题举例分析

假设滑动窗口需要5个小的计数周期,初始化一个长度为5的整数数组,数字代表数组中的哪个元素。

我们知道队列有头有尾。我们从队列的头部获取数据,并将数据插入队列的尾部。括号中的数字表示队列中的元素。

当滑动窗口向前移动时,队列的尾部向右移动一位,队列的头部也向右移动一位。

将队列的尾部和队列的头部向右移动可能会溢出数组,所以让它们返回到数组的起始位置,即图中数组的第一个位置。

关于这个算法的详细介绍,可以看这篇文章:如何用数组实现滑动窗口。

00-1010基于Redis也可以使用类似循环队列的方法,比如定义5 KVs作为数组的5个元素。但是,我之前用了更直观的方式来实现。每个小计数周期都会创建一个KV,同时设置一个绝对超过滑动窗口时间跨度的到期时间,这样未使用的小计数周期就不会一直占用内存。在判断是否触发限流时,累加这些小滑窗的计数值就足够了。当然,在实际实现中,我们需要改进一些细节,比如如何找到这些小的计数周期。会有很多方案,可以保存,也可以临时计算。

这些操作逻辑可以封装在Lua脚本中。因为Lua脚本在热地Redis执行时也是原子操作

s的限流计数在分布式部署时天然就是准确的。

应用算法

这里以限流组件 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 InProcessSlidingWindowAlgorithm(
                new[] {
                		// 构造函数有两个参数:滑动窗口的时间长度、小计数周期的时间长度
                    new SlidingWindowRule(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(1))
                    {
                        ExtractTarget = context =>
                        {
                        		// 提取限流目标
                            return (context as HttpContext).Request.Path.Value;
                        },
                        CheckRuleMatching = context =>
                        {
                        		// 判断当前请求是否需要限流处理
                            return true;
                        },
                        Name="sliding window limit rule",
                        LimitNumber=100, // 限流阈值,这里即5秒最多100次请求
                    }
                })
            );
            ...
        }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            ...
            app.UseRateLimit();
            ...
        }

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

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

  • 这里使用进程内固定窗口算法InProcessSlidingWindowAlgorithm,还可以使用RedisSlidingWindowAlgorithm,需要传入一个Redis连接。两种算法都支持同步和异步方法。

  • 限流阈值是100,限流滑动窗口是5秒,小计数周期是1秒。

  • ExtractTarget用于提取限流目标,这里是每个不同的请求Path。如果有IO请求,这里还支持对应的异步方法ExtractTargetAsync。

  • CheckRuleMatching用于验证当前请求是否限流。如果有IO请求,这里还支持对应的异步方法CheckRuleMatchingAsync。

  • 默认被限流时会返回HttpStatusCode 429,可以在AddRateLimit时使用可选参数error自定义这个值,以及Http Header和Body中的内容。

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

如果还是基于传统的.NET Framework,则需要在Application_Start中注册一个消息处理器RateLimitHandler,算法和规则部分都是共用的,具体可以看Github上的使用说明:https://github.com/bosima/FireflySoft.RateLimit

FireflySoft.RateLimit 是一个基于 .NET Standard 的限流类库,其内核简单轻巧,能够灵活应对各种需求的限流场景。

其主要特点包括:

  • 多种限流算法:内置固定窗口、滑动窗口、漏桶、令牌桶四种算法,还可自定义扩展。

  • 多种计数存储:目前支持内存、Redis两种存储方式。

  • 分布式友好:通过Redis存储支持分布式程序统一计数。

  • 限流目标灵活:可以从请求中提取各种数据用于设置限流目标。

  • 支持限流惩罚:可以在客户端触发限流后锁定一段时间不允许其访问。

  • 动态更改规则:支持程序运行时动态更改限流规则。

  • 自定义错误:可以自定义触发限流后的错误码和错误消息。

  • 普适性:原则上可以满足任何需要限流的场景。

到此,相信大家对“ASP.NET Core中使用滑动窗口限流的问题举例分析”有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/141692.html

(0)

相关推荐

  • http协议安全性分析总结(http网络通信报文实时解析)

    技术HTTP协议消息头的示例代码这篇文章主要介绍HTTP协议消息头的示例代码,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!host=gray-scp-getway.9fbank.com
    x-rea

    攻略 2021年12月14日
  • java中基于线层池Spring-quartz如何实现动态增删除改和暂停恢复定时任务

    技术java中基于线层池Spring-quartz如何实现动态增删除改和暂停恢复定时任务这篇文章主要讲解了“java中基于线层池Spring-quartz如何实现动态增删除改和暂停恢复定时任务”,文中的讲解内容简单清晰,

    攻略 2021年11月15日
  • 如何实现对Samba UAF和内存泄漏漏洞的分析

    技术怎么实现Samba UAF和内存泄露漏洞的分析怎么实现Samba UAF和内存泄露漏洞的分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。0x00 事件

    攻略 2021年12月22日
  • vue权限控制按钮显示隐藏(vue按钮级别权限控制)

    技术vue按钮怎么实现权限控制这篇文章主要讲解了“vue按钮怎么实现权限控制”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vue按钮怎么实现权限控制”吧!一、步骤1.定义

    攻略 2021年12月23日
  • 清除浮动的方法

    技术清除浮动的方法 清除浮动的方法1、直接设置父元素高度:
    特点:①、优点:简单粗暴,方便;②、缺点:有些布局中不能固定父元素的高度。例如:新闻列表、京东推荐模;2、额外标签法:
    (1)、操作:①、在父

    礼包 2021年11月18日
  • hive分区和分桶的示例分析

    技术hive分区和分桶的示例分析这篇文章主要为大家展示了“hive分区和分桶的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“hive分区和分桶的示例分析”这篇文章吧。

    攻略 2021年12月10日