限流算法

一、固定窗口算法

固定窗口算法是在一个固定时间周期内设置请求阈值,在一个时间周期内累计所有请求的请求次数,当小于请求阈值时,正常请求,当达到请求阈值时,执行对应的流控策略。当到达下一个时间周期时,对请求次数进行清零,重新开始计数。

对应该算法的一个缺陷就是在两个时间周期之间,第一个时间周期的末尾和第二个时间周期的开始,如果都出现了突发流量达到请求阈值,则会对后端服务造成影响甚至打爆后端服务。因为在划分的单个时间周期内看都限制了请求上限的,但是在这两个突发流量的时间周期内看是在一定的时间周期内请求数量达到了阈值的2倍。举个例子如下图:

在时间周期A和B中,看他们的限制都为累计请求次数小于阈值,但是在C的时间周期看这个区间就可能出现通过了2倍的请求次数,因为在C的中段会对累计请求次数清零并重新开始计数。所以在面对突发流量时,固定窗口算法无法做出有效流控。

二、滑动窗口算法

针对固定窗口算法的升级版本,滑动窗口算法在面对上述问题时有能力解决。滑动窗口算法在单个时间周期进行进一步的划分,划分为N个小周期,具体划分策略由实现决定,并分别记录每个小周期内的请求次数,随着时间滑动整个时间周期,删除过期的小周期。举个例子如下:

上图一个时间周期划分了5个小周期,单个时间周期内的请求阈值为40次,上图中每过一个小周期的时间,会抛弃掉这一个小的时间周期,但是当前的累计请求次数仅仅减去小的时间周期内累计的请求次数,后续能接收的请求数量就是时间周期阈值减去当前所有小周期请求次数。不过缺点就是针对划分的小周期请求次数需要存储在内存中,这样就需要找一个内存开销和流控周期的平衡点,因为当对时间周期内小周期划分的越精细就对于流量限制就会更精细,随之带来就是小周期内请求次数的存储开销。

三、漏桶算法

漏桶算法顾名思义,就是设计一个类似漏水的桶拦截在请求处,当访问请求到达时,就放入桶中,桶的容量有一定限制,如果桶中的请求数量达到上限,此时执行限流策略。然后桶中的请求会按照一定速率通过,去访问具体请求。直到桶中数据为空。

对应该算法的好处就是能够对流量进行绝对的速率控制,对于突发流量也可以进行有效限制,但是好处也是坏处,这样的话在当前服务压力较小时,请求流量也是一如既往,对于后端服务而言是没有达到资源充分利用的。

四、令牌桶算法

令牌桶算法就是一个较为平衡的算法,可以在一定程度上达到"削峰平谷"的效果。令牌桶的实现思想为:每个请求是否通过要看能否拿到令牌,然后设置了一个存储令牌的桶,并对桶内的令牌上限做了限制。同时对于令牌而言是以一定速率进行生成。对于令牌桶的思想可以结合生产者消费者思想进行理解。例如:在流量稳定时,每秒请求5个请求,令牌的产生速率为每秒5个,此时生产和消费达到平衡。如果每秒请求3个请求,令牌的产生速率为每秒5个,此时每秒盈余2个令牌,就会存储到桶中,桶的上限为100。在经过50s后桶的令牌上限达到100,后续如果有突发流量200个,此时会直接放过100个请求,后续100个请求需要执行限流策略,或是直接返回失败或者进行排队等待令牌生成。

更多资料:0voice · GitHub

相关推荐
mit6.824几秒前
archived
后端·python·flask
用户298698530149 分钟前
效率工具分享:3 款免费 Markdown 转 Word 在线转换器
人工智能·后端
程序员天天困10 分钟前
Spring Boot i18n 国际化实战:从资源文件到多语言接口完整指南
spring boot·后端·编程语言
睡觉时不困44215 分钟前
8.conda 与 uv 环境管理完全指南:从概念到实战避坑
后端
是小李呀16 分钟前
Spring Boot 配置加载机制解析:Docker 部署中 `spring.profiles.active` 与 `spring.config.location` 的本质区别
后端
步行cgn18 分钟前
MyBatis 多参数绑定错误:Parameter 'name' not found 详解与解决方案
后端
步行cgn22 分钟前
MyBatis 对单个简单类型参数的默认处理详解
后端
吃饱了得干活23 分钟前
Java并发安全:看这一篇就懂了!
java·后端·面试
早点睡97524 分钟前
向量检索原理入门:从 ANN 到 HNSW
后端·面试
Augustzero26 分钟前
为什么高性能调度器都在“偷任务”?从无锁队列看懂工作窃取
c++·后端