常见的限流方案
从实现方式上来讲,限流可分为简单计数器限流、滑动窗口限流,基于漏桶和令牌桶算法的限流。
从是否支持多机拓展上来讲,又分为单机限流和分布式限流。单机限流大多通过线程锁的方式实现,而分布式限流多借助于Redis等中间件。
简单计数器限流
通过维护单位时间内的请求次数来实现限流,当请求次数超过最大限制时拒绝访问。这种实现方式的好处是实现起来较为简单,缺点是可能会产生“毛刺”。如下图。
滑动窗口限流
滑动窗口也是维护单位时间内的请求次数,其与简单计数器的区别是,滑动窗口的粒度更细,将一个大的时间窗口划分为若干个小的时间窗口,通过滑动时间删除小的时间窗口,以此来避免简单计数器的“毛刺”问题。如下图。
基于漏桶算法限流
漏桶算法将流量放入一个固定容量的“漏斗”中,以恒定速度将流量进行输出。当“漏斗”装满时,拒绝掉涌入的流量。
基于令牌桶算法限流
令牌桶算法每隔一段时间就将一定量的令牌放入桶中,获取到令牌的请求直接访问后段的服务,没有获取到令牌的请求会被拒绝。同时令牌桶有一定的容量,当桶中的令牌数达到最大值后,不再放入令牌。
几种方案各有优劣,需要结合实际场景进行选型。
方案 | 优势 | 劣势 |
---|---|---|
计数器 | 实现最为简单方便 | "毛刺"现象 |
滑动窗口 | 应对突发流量能力强,可配置性强 | 取决于窗口粒度,非严格均匀,流量整形效果弱 |
漏桶 | 流量整形效果最好,输出流量最平滑(均匀输出) | 应对突 |