ASP.NET Core中使用令牌桶算法限流1

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: ASP.NET Core中使用令牌桶算法限流1

在服务限流时一般会限制某个时间周期内的请求数,简单点会采用固定窗口算法(也称计数器算法),这种算法实现相对简单,也很高效;但在实际的应用场景中请求并不是特别均匀,某些情况下会产生一些瞬时的突发流量,然后很快恢复正常,很多时候这并不会对系统产生破坏性的影响,但是固定窗口算法不能很好的处理这种情况。

比如某个数据查询接口限流每秒100次请求,绝大多数的时间里都不会超过这个数,但是偶尔某一秒钟会达到120次请求,接着很快又会恢复正常。此时如果采用固定窗口算法会触发限流,用户的正常访问会被干扰,体验上不太好;如果接口的调用方还有重试的逻辑,则在后续的时间窗口内系统可能收到更多的请求,然后更多的请求被限流,又产生更多的重试请求,循环往复让系统的负担愈加沉重,严重的话可能导致系统崩溃。

假设上文中120次的请求不会对系统稳定性带来实质性的影响,则可以在一定程度上允许这种瞬时的突发流量,从而为用户带来更好的使用体验,也可一定程度上避免因为限流重试导致系统负担进一步加重的问题。本文就介绍一种令牌桶的算法来应对这个情况。


算法原理


说了这么多,那么令牌桶算法怎么解决问题的呢?请看下图:

1689133395528.png


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


算法实现


这里讲两种实现方法:进程内即内存令牌桶算法、基于Redis的令牌桶算法。


进程内即内存令牌桶算法


这里在请求时计算投放数量,没有单独的投放处理,比固定窗口算法麻烦一些,但是仔细阅读,也很容易理解。

使用字典,Key是限流目标,Value包括当前令牌桶令牌数和上次令牌投放时间。初始状态下,认为每个限流目标的令牌桶是装满的,即令牌桶令牌数=令牌桶容量,不过仅在处理中发现限流目标的令牌桶不存在时才创建这个令牌桶。

请求进入后,根据限流目标在字典中查找:

  • 如果找不到,则创建令牌桶,并设置令牌数为:令牌桶容量-本次请求消耗令牌数,设置上次令牌投放时间为:当前时间。
  • 如果找到,则计算当前时间与上次令牌投放时间之间的间隔:
  • 如果大于等于令牌投放时间间隔,则计算令牌数为:max(令牌桶令牌数+令牌投放数量,令牌桶容量)-本次请求消耗令牌数,上次令牌投放时间为:当前时间。
  • 如果小于令牌投放时间间隔,则计算令牌数为:令牌桶令牌数-本次请求消耗令牌数。‘
  • 如果计算出的令牌数小于0,则触发限流,否则更新到令牌桶中。

在C#语言中可以使用MemoryCache,它的缓存项有一个过期时间,可以自动回收一些很少使用或者不再使用的令牌桶,减少内存占用。

进程内算法最适合单实例处理的程序限流,多实例处理的情况下可能每个实例收到的请求数不均匀,不能保证限流效果。


基于Redis的令牌桶算法


Redis作为KV存储,类似于字典,而且也自带过期时间。处理请求时,首先从请求中提取限流目标,然后根据限流目标去Redis中查找,其处理规则和内存算法一样,只不过使用了两个Redis KV:

  • 限流目标的令牌桶,Value是当前令牌数。
  • 限流目标的上次令牌投放时间,Value是上次投放令牌的时间戳。

这些操作逻辑可以封装在一个Lua script中,因为Lua script在Redis中执行时也是原子操作,所以Redis的限流计数在分布式部署时天然就是准确的。



相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
19天前
|
数据可视化 网络协议 C#
C#/.NET/.NET Core优秀项目和框架2024年3月简报
公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(每周至少会推荐两个优秀的项目和框架当然节假日除外),公众号推文中有项目和框架的介绍、功能特点、使用方式以及部分功能截图等(打不开或者打开GitHub很慢的同学可以优先查看公众号推文,文末一定会附带项目和框架源码地址)。注意:排名不分先后,都是十分优秀的开源项目和框架,每周定期更新分享(欢迎关注公众号:追逐时光者,第一时间获取每周精选分享资讯🔔)。
|
1月前
|
开发框架 算法 搜索推荐
C# .NET面试系列九:常见的算法
#### 1. 求质数 ```c# // 判断一个数是否为质数的方法 public static bool IsPrime(int number) { if (number < 2) { return false; } for (int i = 2; i <= Math.Sqrt(number); i++) { if (number % i == 0) { return false; } } return true; } class Progr
59 1
|
3月前
|
开发框架 前端开发 JavaScript
盘点72个ASP.NET Core源码Net爱好者不容错过
盘点72个ASP.NET Core源码Net爱好者不容错过
72 0
|
1月前
|
开发框架 人工智能 .NET
C#/.NET/.NET Core拾遗补漏合集(持续更新)
C#/.NET/.NET Core拾遗补漏合集(持续更新)
|
1月前
|
开发框架 中间件 .NET
C# .NET面试系列七:ASP.NET Core
## 第一部分:ASP.NET Core #### 1. 如何在 controller 中注入 service? 在.NET中,在ASP.NET Core应用程序中的Controller中注入服务通常使用<u>依赖注入(Dependency Injection)</u>来实现。以下是一些步骤,说明如何在Controller中注入服务: 1、创建服务 首先,确保你已经在应用程序中注册了服务。这通常在Startup.cs文件的ConfigureServices方法中完成。例如: ```c# services.AddScoped<IMyService, MyService>(); //
65 0
|
2月前
|
开发框架 前端开发 .NET
福利来袭,.NET Core开发5大案例,30w字PDF文档大放送!!!
为了便于大家查找,特将之前开发的.Net Core相关的五大案例整理成文,共计440页,32w字,免费提供给大家,文章底部有PDF下载链接。
37 1
福利来袭,.NET Core开发5大案例,30w字PDF文档大放送!!!
|
2月前
|
算法 BI API
C#/.NET/.NET Core优秀项目和框架2024年1月简报
C#/.NET/.NET Core优秀项目和框架2024年1月简报
|
3月前
|
机器学习/深度学习 编解码 算法
Yolov5改进算法之添加Res2Net模块
Res2Net(Residual Resolution Network)是一种用于图像处理和计算机视觉任务的深度卷积神经网络架构。它旨在解决传统的ResNet(Residual Network)存在的问题,如对不同尺度和分辨率特征的建模不足以及网络深度受限的问题。Res2Net通过引入多分支的结构和逐级增加的分辨率来提高网络的表达能力,从而在各种视觉任务中取得了显著的性能提升。
|
1月前
|
传感器 算法 计算机视觉
基于肤色模型和中值滤波的手部检测算法FPGA实现,包括tb测试文件和MATLAB辅助验证
该内容是关于一个基于肤色模型和中值滤波的手部检测算法的描述,包括算法的运行效果图和所使用的软件版本(matlab2022a, vivado2019.2)。算法分为肤色分割和中值滤波两步,其中肤色模型在YCbCr色彩空间定义,中值滤波用于去除噪声。提供了一段核心程序代码,用于处理图像数据并在FPGA上实现。最终,检测结果输出到&quot;hand.txt&quot;文件。
|
1月前
|
机器学习/深度学习 算法 计算机视觉
基于yolov2深度学习网络的视频手部检测算法matlab仿真
基于yolov2深度学习网络的视频手部检测算法matlab仿真