限流算法
限流:限制流量,好处也不言而喻。
- 比如限制流量,减小服务器压力
- 而且在企业开发中,每个游的承受能力是不同的,若上游流量大且承受能力强,下游承受能力没那么强,上游的流量突然增进,很容易打垮下游服务
- 避免非正常的一个请求
计数器算法
最简单也是最容易想的一个算法。
固定窗口计数
- 将时间划分为多个窗口。
- 在每个窗口内每有一次请求就将计数器加一。
- 如果计数器超过了限制数量,则本窗口内所有的请求都被丢弃当时间到达下一个窗口时,计数器重置。
缺点:假设我们限制每秒钟只能处理10个请求,在上一个窗口的后半秒中通过了10个请求,在当前窗口的前半秒中又通过了10个请求,此时就在一秒钟内通过了20个请求,达到了窗口限制的两倍,这时就有可能超出了服务器的处理能力,从而导致宕机。
滑动窗口计数
固定窗口计数因为两个窗口一半能看成新窗口,所以可能导致问题,我们将窗口慢慢滑动起来,动态的维护。
- 将时间划分为多个区间。
- 在每个区间内每有一次请求就将计数器加一维持一个时间窗口,占据多个区间。
- 每经过一个区间的时间,则抛弃最老的一个区间,并纳入最新的一个区间。
- 如果当前窗口内区间的请求计数总和超过了限制数量,则本窗口内所有的请求都被丢弃。
缺点:但是流量是平滑到来的吗?不是,晚上7点和凌晨3点的流量可能量级的差距相当大。热点等时间会存在突发的流量激增,在这种情况下很容易就会导致服务器性能打满,从而出现宕机等情况。
漏桶算法
- 将每个请求视作水滴放入漏桶进行存储。
- 漏桶以固定速率向外漏出请求来执行,如果漏桶空了则停止漏水。
- 如果漏桶满了则多余的水滴会因为溢出被直接丢弃。
无论请求有多少,无论请求速率有多大,漏桶都会接收下来,同时漏桶里流出来的请求是固定速率的,即使是在流量激增的情况下,也保证了服务器能够平滑的处理。当漏桶因为容量限制放不下更多的请求时,就会选择丢弃部分请求。这种思路其实就是一种宽进严出的策略。
缺点:当短时间内有大量的突发请求时,即便此时服务器没有任何负载,每个请求也都得在队列中等待一段时间才能被响应。所以漏桶策略适用于间隔性突发流量且流量不用即时处理的场景。
令牌桶算法
桶里面放着很多令牌,拥有令牌的,服务器才处理。
- 令牌以固定速率生成。
- 生成的令牌放入令牌桶中存放,如果令牌桶满了则多余的令牌会直接丢弃。当请求到达时,会尝试从令牌桶中取令牌,取到了令牌的请求可以执行。
- 如果桶空了,那么尝试取令牌的请求会被直接丢弃。
令牌桶算法其实就可以看成生产者消费者,令牌桶固定速率生产令牌,请求来消费令牌,若没有则丢弃,若有,则消费。