Jonsson Yan' Blog

怕什么真理无穷,进一步有进一步的欢喜。

0%

常见的限流算法

常见的限流算法如下

  1. 固定窗口限流算法
  2. 滑动窗口限流算法
  3. 漏桶算法
  4. 令牌桶算法

限流是什么?

限流顾名思义就是限流流量,也叫流量控制,在系统面临高并发、大流量请求的情况下,限制新的流量对系统的访问,从而保证系统服务的安全性。举个例子,一个电影院只有 200 个座位,并出售 200 张门票,每个门票代表一个人,代表这个电影院只可以进入 200 人,多余的人就买不到票也就进不了电影院。

为什么要实现限流

限流起到保证系统稳定的作用。如果一个系统不限制流量,假如有大量的流量指向系统,比如在秒杀活动、双十一促销等场景下,点击量剧增,用户的流量巨增,但是服务的处理能力是有限的,如果不能处理好大流量请求,系统很容易发生瘫痪。

固定窗口限流算法

固定窗口限流算法又称计数器算法(Fixed Window),通过在单位时间内维护的计数器来控制该时间单位内的最大访问量。

设置没小时不超过 3 个请求,超出阈值则拒绝请求,未超出阈值则接受请求并将计数器加 1,当时间窗口结束时,重置计数器为 0。

优点

实现简单,容易理解。

缺点

  1. 一段时间内服务不可用。

比如 10s 内限流 100 此请求,但是 0s-1s 就来了 100 个请求,则 2s-10s 的请求都是被拒绝的。

  1. 窗口切换时可能会出现两倍阈值的请求。

比如 10s 内限流 100 此请求。0s-9.99s 没有请求,而在 9.99s-10s 之间来了 100 个请求,当切换到下一个窗口时,在 0s-0.01s 之间来了 100 个请求,而我们的阈值设置的是每 10s100 次请求,通过的请求达到了阈值的两倍

滑动窗口限流算法

滑动窗口限流算法是固定窗口限流算法的改进,弥补了固定窗口限流算法可能会出现两倍阈值请求的缺点。为了防止瞬时流量,可以把固定窗口近一步划分成多个格子,每次向后移动一小格,而不是固定窗口大小。

在滑动窗口的情况加就不存在窗口切换导致请求达到阈值两倍的情况,因为它根本不会切换窗口,每次都是往后移动一格,如图所示,假设 1s 内只接受 100 个请求,在绿色位置接受了 100 个请求,当到了黄色位置,应为在窗口内绿色已经达到了 100 个请求的阈值,所以在黄色位置就不会再接受请求。

特点

  1. 弥补了固定窗口限流算法的缺点即避免了固定窗口算法在窗口切换时可能会产生两倍于阈值流量请求的问题。
  2. 和漏桶算法相比,新来的请求也能够被处理到,避免了漏桶算法的饥饿问题。

漏桶算法

举个例子,假如有一个桶,桶下面有一个小洞,每秒以固定的速率在滴水,当注入的水超过桶的容量时就会溢出。这里的滴水就代表我们处理的请求,注水就代表用户流量,桶就代表我们存储的请求,溢出就代表被丢弃的请求。在系统看来,请求永远是以平滑的传输速率过来,从而起到了保护系统的作用。漏桶算法实现可以借助队列来实现,队列中存储我们需要处理的请求即可。

特点

  1. 漏桶的漏出速率是固定的,可以起到整流的作用。
  2. 不能解决流量突发的问题。

假设桶的容量是 5,“漏”的速度是 2 个/s,当突然有 10 个请求时,首先丢弃 5 一个请求,还有 5 个请求放到桶中,而这 5 个请求还只是放在桶中在等待处理,所以并没有解决流量突发的问题。

令牌桶算法

令牌桶算法是为了解决漏桶算法的缺点(不能解决流量突发)。

如图所示,以恒定的速度往桶中生成令牌,如果桶满了那就丢弃,每当来一个请求,就从桶中拿走一个令牌,如果桶中没有令牌即请求没有拿到令牌,则拒绝这个请求。所以令牌桶算法和漏桶算法的区别就是允许一定程度的流量突发。

特点

除了能够在限制调用的平均速率的同时还允许一定程度的流量突发。