网关限流算法

为什么要限流呢?

以秒杀业务为例,一个商品可只出售 100 件的情况下,可能会有上万的人在同一时间去抢。这个时候只有百分之一的请求是有效的。如果我们还无脑的把计算资源耗费在这无用的百分之九十九上面,不是很 sb?

所以我们为了让计算资源做更有价值的事,同时也让我们的系统更加的健壮,我们可能只处理 2~300 的请求,对于其他的请求则直接丢弃。而要实现这一效果,就要用到限流算法。

有哪些限流算法呢?

1. 固定窗口计数器算法

规定我们单位时间处理的请求数量。比如我们规定一个接口一分钟智能访问 100 次的话,使用固定窗口计数器算法这么实现:

给定一个变量 counter 来记录处理的请求数量,当 1 分钟之内处理一个请求之后 counter+1,1 分钟之内如果 counter = 100,后续的请求就会被全部拒绝,等 1 分钟结束后,counter 回归到 0,重新计数。

但这种限流算法无法解决短时间内流量的激增。

2. 滑动窗口计数器算法

相当于细粒度的固定窗口计数器。

他把时间以一定比例分片,例如我们的接口限流每分钟处理 60 个请求,我们可以把 1 分钟分为 60 个窗口,每隔 1s 移动一次,每个窗口 1s 只能处理不大于 60/60 的请求,如果当前窗口的请求计数总和超过了限制的数量的话,就不再处理其他请求。

3. 桶漏算法

我们可以把发请求的动作比作成注水到水桶,我们处理请求的过程可以比喻为漏桶漏水。我们往桶中以任意速率流入水,以一定的速率流出水。当水超过桶容量则丢弃。

实现:准备一个队列来保存请求,然后我们定期从队列中拿请求来执行就好。

4. 令牌桶算法

令牌桶装的是令牌。请求在被处理之前需要拿到一个令牌,请求处理完毕之后将这个令牌丢弃(删除),我们根据限流的大小,按照一定的速率往桶里添加令牌。

实现:通过一个队列来存放令牌,每当有请求过来时先判断能不能拿到令牌。

它相比于桶漏算法来说,能更好的处理激增流量。假设一段时间内没有请求过来,令牌桶中就会积攒一定数量的令牌(可以我们自己设定桶的容量),当流量激增时,过来的流量就能直接拿到令牌,执行业务,而不向桶漏一样一致保持一定的速率。

updatedupdated2022-06-232022-06-23