限流原理
怎么自己实现限流框架
计数器法
设定一个计数器,和一个阈值,每次请求计数器+1,若达到阈值就限流。简单粗暴
滑动窗口
设定一个时间窗口,分为若干小格,每格有计数器,每格代表一个时间间隔(比如10s),这个间隔内的请求会在他的计数器内累加,那么限流规则就是:将所有格子的计数总数和设定的阈值比较,大于则限流,相比普通一个计数器包含、均衡了一段时间内的负载。
漏桶算法
好像一个装水的桶一样,若水满了就会溢出,这个桶还会以一定速率漏水,水就像请求流量
漏桶算法有以下特点:
- 漏桶具有固定容量,出水速率是固定常量(流出请求)
- 如果桶是空的,则不需流出水滴
- 可以以任意速率流入水滴到漏桶(流入请求)
- 如果流入水滴超出了桶的容量,则流入的水滴溢出(新请求被拒绝)
漏桶限制的是常量流出速率(即流出速率是一个固定常量值),所以最大的速率就是出水的速率,不能出现突发流量。
令牌桶算法
令牌桶算法和漏桶算法的方向刚好是相反的,我们有一个固定容量的桶,桶里存放着令牌(token)。桶一开始是空的,token以 一个固定的速率r往桶里填充,直到达到桶的容量,多余的令牌将会被丢弃。每当一个请求过来时,就会尝试从桶里移除一个令牌,如果没有令牌的话,请求无法通过。
令牌桶有以下特点:
- 令牌按固定的速率被放入令牌桶中
- 桶中最多存放 B 个令牌,当桶满时,新添加的令牌被丢弃或拒绝
- 如果桶中的令牌不足 N 个,则不会删除令牌,且请求将被限流(丢弃或阻塞等待)
令牌桶限制的是平均流入速率(同时还允许一定程度的突发调用,只要有令牌就可以处理,支持一次拿3个令牌,4个令牌),并允许一定程度突发流量。
计数器和滑动窗口比较
计数器算法实现起来最简单,可以看成是滑动窗口的低精度实现。滑动窗口由于需要存储多份的计数器(每一个格子存一份),所以滑动窗口在实现上需要更多的存储空间。也就是说,如果滑动窗口的精度越高,需要的存储空间就越大。
漏桶算法和令牌桶算法比较
漏桶 | 令牌桶 | |
---|---|---|
何时拒绝请求 | 流入请求速率任意,以固定的速率流出请求,流入请求数超过漏桶容量,拒绝请求 | 以固定速率往桶中添加令牌,桶中无令牌则拒绝请求 |
速率限制 | 限制常量流出速率,从而平滑突发流入速率 | 限制平均流入速率,允许一定程度的突发请求(允许一次拿多个令牌) |