本文主要介绍限流算法的知识。包括漏桶、令牌桶、时间窗口以及它们的特点和实现。
漏桶
流入速率
流入流量+桶内流量<=桶的总容量-->不限流
流入流量+桶内流量>桶的总容量-->限流
流出速率
按固定速率流出
实现:https://www.freesion.com/article/2663497563/
令牌桶
放入令牌速率
按一定速率放入令牌(比如按一定时间间隔放入多少令牌),令牌数量超过最大令牌数量则限流
流出速率
每次流出前,都需要先从令牌桶中先获取对应的令牌数量。所以流出的速率是由桶内令牌的数量决定的。
实现:https://www.jianshu.com/p/490737f31260
漏桶VS令牌桶
漏桶算法和令牌桶算法最明显的区别是令牌桶算法允许流量一定程度的突发。因为默认的令牌桶算法,取走令牌是不需要耗费时间的,也就是说,假设桶内有100个令牌时,那么可以瞬间允许100个请求通过。
令牌桶算法由于实现简单,且允许某些流量的突发,对用户友好,所以被业界采用地较多。
固定窗口(计数器)
计数器算法是使用计数器在周期内累加访问次数,当达到设定的限流值时,触发限流策略。下一个周期开始时,进行清零,重新计数。
实现简单,但存在临界点问题,比如一个周期是10秒,每个周期限制100个请求。第一个周期的最后5秒和下一个周期的开始5秒时间段内,分别涌入100的访问量,虽然没有超过每个周期的限制量,但是整体上10秒内已达到200的访问量,已远远超过服务器的负载能力,由此可见,计数器算法方式限流对于周期比较长的限流,存在很大的弊端。
实现:可以通过redis实现(有效期+自增)
滑动窗口
滑动窗口算法是将时间周期分为 N 个小周期,分别记录每个小周期内访问次数,并且根据时间滑动删除过期的小周期。
是计数器的升级版,解决了临界点问题。但计数多且复杂。滑动窗口的格子划分的越多,滑动窗口的滚动就越平滑,限流的统计就会越精确。
实现:http://www.qishunwang.net/news_show_51222.aspx
固定时间窗口VS滑动时间窗口
计数器算法是最简单的算法,可以看成是滑动窗口的低精度实现。滑动窗口由于需要存储多份的计数器(每一个格子存一份),所以滑动窗口在实现上需要更多的存储空间。也就是说,如果滑动窗口的精度越高,需要的存储空间就越大。
参考
1.https://blog.csdn.net/weixin_41846320/article/details/95941361
2.https://blog.csdn.net/fgszdgbzdb/article/details/102670291