限流
简介
限流是保障服务稳定的一个方式(此篇文章以摘要参考文档为主)
方案
- 信号量
- 计数器
- 滑动窗口
- 漏桶算法
- 令牌桶算法
- 分布式限流
信号量
信号量实际上就是限制系统的并发量,来达到限流的目的。
实现方式与一把可以多次获取的锁非常相似。
计数器
比如限制1秒钟内请求数最多为10个,每当进来一个请求,则计数器+1。当计数器达到上限时,则触发限流。时间每经过1秒,则重置计数器
- 主要问题
- 第一秒的后半秒和第二秒的前半秒将限制数量用完,但此一秒内系统流量超过了单个一秒的限制
- 一秒的前半秒将限制数量用完,则后半秒系统无法接受请求
滑动窗口
滑动窗口本质上是一种粒度更细的计数器,每次窗口滑动时,重置前100ms之间内的计数,而不是完整的1s
主要问题和计数器方案相同
漏桶
漏桶(Leaky Bucket)算法思路如下,请求先进入到漏桶里,漏桶以一定的速度放出请求给系统响应,当漏桶中无法接收更多的请求则丢弃,这样可以强行限制请求的处理速率
- 主要问题
- 处理速度固定,无法处理短时间内突发的超高请求
令牌桶
令牌桶算法思路如下,系统以固定的速率往令牌桶中放入令牌,请求进入时,从桶中取走令牌,当桶中无令牌可取时,触发限流
解决的问题:可以处理突发流量
分布式限流
分布式限流的大致思路是需要将核心计数组件放到redis中,具体的方案是使用redis中的lua脚本来实现
具体实现详见参考文档2
小结
限流只是一个保障系统的方法,在实际应用中令牌桶应当是更加常见的,但是当然也并非完美。
Java中有Guava包提供了几种限流算法的实现,同样也具有很大的参考意义。