限流算法及其应用

在开发高并发系统时有三把利器用来保护系统:缓存、降级和限流。限流(Rate Limit),限流的目的是为了保护系统不被瞬时大流量冲垮,常见的应用场景类似秒杀,大促峰值QPS在2w以上。

目前比较常见的限流算法有:

  • 计数器固定窗口算法
  • 计数器滑动窗口算法
  • 漏桶算法
  • 令牌桶算法

1. 计数器固定窗口算法

      计数器固定窗口算法是使用计数器在周期内累加访问次数,当达到设定的限流值时,触发限流策略。下一个周期开始时,进行清零,重新计数。

     缺点:计数器固定窗口算法通常用于QPS限流和统计总访问量,对于秒级以上的时间周期来说,会存在一个非常严重的问题,那就是临界问题,比如:

假设我们设定1秒内允许通过的请求阈值是200,如果有用户在时间窗口的最后几毫秒发送了200个请求,紧接着又在下一个时间窗口开始时发送了200个请求,那么这个用户其实在一秒内成功请求了400次,显然超过了阈值但并不会被限流。

2.计数器滑动窗口算法

    滑动窗口算法是将时间周期分为N个小周期,分别记录每个小周期内访问次数,并且根据时间滑动删除过期的小周期。

     如下图,假设时间周期为1min,将1min再分为2个小周期,统计每个小周期的访问数量,则可以看到,第一个时间周期内,访问数量为75,第二个时间周期内,访问数量为100,超过100的访问则被限流掉了。

由此可见,当滑动窗口的格子划分的越多,那么滑动窗口的滚动就越平滑,限流的统计就会越精确。

此算法可以很好的解决固定窗口算法的临界问题。滑动窗口限流法其实就是计数器固定窗口算法的一个变种。流量的过渡是否平滑依赖于我们设置的窗口格数也就是统计时间间隔,格数越多,统计越精确。

3. 漏桶算法

      漏桶算法以一个常量限制了出口流量速率,因此漏桶算法可以平滑突发的流量。其中漏桶作为流量容器我们可以看做一个FIFO的队列,当入口流量速率大于出口流量速率时,因为流量容器是有限的,当超出流量容器大小时,超出的流量会被丢弃。

                                                                  

 

漏桶算法的特点

  • 漏桶具有固定容量,出口流量速率是固定常量(流出请求)

  • 入口流量可以以任意速率流入到漏桶中(流入请求)

  • 如果入口流量超出了桶的容量,则流入流量会溢出(新请求被拒绝)

漏桶算法限制了流出速率是一个固定常量值,所以漏桶算法不支持出现突发流出流量。

4.令牌桶算法

   令牌桶算法是网络流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一种算法。典型情况下,令牌桶算法用来控制发送到网络上的数据的数目,并允许突发数据的发送。

    令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。从原理上看,令牌桶算法和漏桶算法是相反的,一个“进水”,一个是“漏水”。

   

 

     Google的Guava包中的RateLimiter类就是令牌桶算法的解决方案。

总结:

     桶算法与令牌桶算法的区别在于,漏桶算法能够强行限制数据的传输速率,令牌桶算法能够在限制数据的平均传输速率的同时还允许某种程度的突发传输。

参考:https://blog.csdn.net/weixin_41846320/article/details/95941361

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章