当前位置:   article > 正文

限流的4种策略--固定窗口、滑动窗口、漏桶、令牌桶_限流策略

限流策略

01 Why

分布式系统中,由于接口API无法控制上游调用方的行为,因此当瞬时请求量突增时,会导致服务器占用过多资源,发生响应速度降低、超时、乃至宕机,甚至引发雪崩造成整个系统不可用。
限流,Rate Limiting,就是对API的请求量进行限制,对于超出限制部分的请求作出快速拒绝、快速失败、丢弃处理,以保证本服务以及下游资源系统的稳定。

哪些原因会带来瞬时请求量突增?
1,热点业务、突发热点数据带来的激增。例如微博热搜的爆点。
2,上游系统的bug导致。
3,恶意的攻击流量。
实现限流的方法很多,一句话来讲,就是限制每秒钟内API可处理的请求量。常见的有以下几种算法:固定窗口计数法、滑动窗口计数法、漏桶算法、令牌桶算法。


02 How - 固定窗口计数法


固定窗口计数法的思路是:

  1. 将时间划分为固定的窗口大小,例如1s
  2. 在窗口时间段内,每来一个请求,对计数器加1。
  3. 当计数器达到设定限制后,该窗口时间内的之后的请求都被丢弃处理。
  4. 该窗口时间结束后,计数器清零,从新开始计数。

固定窗口计数法是最简单、也最直观的限流算法。但在最坏的情况下,会让通过的请求量是限制数量的两倍,例如,假设限制的是每个窗口5个请求:

  1. T窗口的前1/2时间 无流量进入,后1/2时间通过5个请求;
  2. T+1窗口的前 1/2时间 通过5个请求,后1/2时间因达到限制丢弃请求。
  3. 因此在 T的后1/2和(T+1)的前1/2时间组成的完整窗口内,通过了10个请求。


03 How - 滑动窗口计数法

滑动窗口计数法的思路是:

  1. 将时间划分为细粒度的区间,每个区间维持一个计数器,每进入一个请求则将计数器加一。
  2. 多个区间组成一个时间窗口,每流逝一个区间时间后,则抛弃最老的一个区间,纳入新区间。如图中示例的窗口T1 变为 窗口T2
  3. 若当前窗口的区间计数器总和超过设定的限制数量,则本窗口内的后续请求都被丢弃。

04 How - 漏桶算法

漏桶算法的思路是:
1,每个请求看作“水滴” 一样,放入漏桶中暂存。
2,漏桶以固定的速率,漏出请求来执行;如果漏桶空了,则停止漏水。3,如果漏桶满了,则新来的请求会被丢弃。
很明显,漏桶算法在实现的数据结构会选择有容量限制的队列,请求执行者定期定点从队列取出请求来执行,新来的请求会被暂存在队列中或者被丢弃。

漏桶算法的缺点是,不论当前系统的负载压力如何,所有请求都得进行排队,即便此时服务器负载处于低位。


05 How - 令牌桶算法

令牌桶算法:
1,令牌按固定速率发放,生成的令牌放入令牌桶中。2,令牌桶有容量限制,当桶满时,新生成的令牌会被丢弃。
3,请求到来时,先从令牌桶中获取令牌,如果取得,则执行请求;如果令牌桶为空,则丢弃该请求。
令牌桶算法可以把请求平均分散在时间段内,是使用较为广发的限流算法。


06 单点应用限流 vs 分布式集群限流

单点应用下,对应用进行限流,既能满足本服务的需求,又可以很好的保护好下游资源。在选型上,可以采用Google Guava的RateLimiter即可。

而在多机部署场景下,对单点的限流,则不能达到最好效果,需要引入分布式限流。分布式限流的算法,依然可以采用令牌桶算法,只不过将令牌桶的发放、存储改为全局的模型。真正实现中,可以采用redis+lua的方式,通过把逻辑放在redis端,来减少调用次数。


lua的逻辑如下:
1,redis中存储剩余令牌的数量cur_token,和上次获取令牌的时间last_time。
2,在每次申请令牌时,可以根据(当前时间cur_time - last_time)的时间差 乘以 令牌发放速率,算出当前可用令牌数。
3,如果有剩余令牌,则准许请求通过;否则不通过。


07 总结

不论出于什么风险,要保证系统的抗压能力,限流是不可缺少的一个环节。
单点应用场景下,常用的算法有固定窗口计数法、滑动窗口计数法、漏桶法、令牌桶法。分布式场景下,需要将限流算法的存储信息全局化,而为了性能和一致性,需要进行深度优化。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/274631?site
推荐阅读
相关标签
  

闽ICP备14008679号