限流算法

一、固定窗口算法

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

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

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

二、滑动窗口算法

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

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

三、漏桶算法

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

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

四、令牌桶算法

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

更多资料:0voice · GitHub

相关推荐
devlei2 小时前
从源码泄露看AI Agent未来:深度对比Claude Code原生实现与OpenClaw开源方案
android·前端·后端
努力的小郑4 小时前
Canal 不难,难的是用好:从接入到治理
后端·mysql·性能优化
Victor3564 小时前
MongoDB(87)如何使用GridFS?
后端
Victor3564 小时前
MongoDB(88)如何进行数据迁移?
后端
小红的布丁5 小时前
单线程 Redis 的高性能之道
redis·后端
GetcharZp5 小时前
Go 语言只能写后端?这款 2D 游戏引擎刷新你的认知!
后端
宁瑶琴6 小时前
COBOL语言的云计算
开发语言·后端·golang
普通网友7 小时前
阿里云国际版服务器,真的是学生党的性价比之选吗?
后端·python·阿里云·flask·云计算
IT_陈寒7 小时前
Vue的这个响应式问题,坑了我整整两小时
前端·人工智能·后端
Soofjan8 小时前
Go 内存回收-GC 源码1-触发与阶段
后端