文章

限流算法-时间窗口算法

限流算法-时间窗口算法

用途

假设QPS是2。那么时间窗口大小设置为1s,并且其中的大小设置为2。

从而保证 [0, 1], [1, 2], … , [n - 1, n] 每个时间窗口内,请求量都是1。

实现

  1. 限制时间窗口内的请求总数(size)
  2. 时间窗口内的已有请求量(num)定时刷新
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
 * 1、限制时间窗口内的请求总数(size)
 * 2、时间窗口内的已有请求量(num)定时刷新
 */
let lastTime = Date.now(); // 时间窗口上次刷新的时间
let internal = 10000; // 时间窗口时间大小,单位ms
let size = 2; // 时间窗口内能通过的请求总数
let num = 0; // 时间窗口内目前已通过的请求数

function check() {
    let nowTime = Date.now();
    if (nowTime - lastTime > internal) {
        // 定时(internal)清空时间窗口
        num = 0;
        lastTime = nowTime;
    }

    if (num >= size) {
        return false;
    }
    ++num;
    return true;

测试代码效果:每10s,打印2遍,相当于放通2个请求

1
2
3
4
5
6
7
// 测试代码
// c
while (1) {
    if (check()) {
        console.log(">>> 请求可以通过");
    }
}

缺陷

时间窗口不是平滑限流。

例如对于 [0, 1], [1, 2], QPS限制是2。假设在 0.8s 和 1.2s的时候各有2个请求打入,能通过check()函数。但是对于 [0.5, 1.5] 这段时间内,请求数是4,而没有限制成2。

平滑流量需要使用漏桶算法或者令牌桶算法。参考 限流算法-漏桶和令牌桶

本文由作者按照 CC BY 4.0 进行授权