文章

实现严格 API 限流: throttling 函数

背景

在现代 Web 应用中,用户频繁的重复请求可能会对系统资源造成巨大压力,甚至引发潜在的安全问题。前端的防抖或节流机制尽管能在一定程度上减少重复请求,但无法从根本上杜绝恶意行为。为了更好地保护后端服务的稳定性,我们通常会在服务端实现请求限流。本文将介绍一个基于 Node.js 和 Redis 的限流函数 throttling,并探讨其在严格 API 限流中的应用。

核心代码

下面是实现限流功能的 throttling 函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
 * ip                  标识用户身份
 * throttlingPeriod    限流时间,单位 s
 * apiThrottlingLimit  限流时间内的最大请求次数
 */
throttling: async function throttling(ip, cacheKeySuffix, throttlingPeriod, apiThrottlingLimit) {
  try {
    if (!ip) {
      return { 'errCode': 401 };
    }

    throttlingPeriod = throttlingPeriod || 1;
    let expireType = 'EX';
    if (throttlingPeriod < 1) {
      expireType = 'PX';
      throttlingPeriod = throttlingPeriod * 1e3;
    }

    apiThrottlingLimit = parseInt(apiThrottlingLimit) || 1;

    const key = 'api.throttling.' + ip + '.' + cacheKeySuffix;

    const count = await redis.incrby(key, 1);

    await redis.set(key, count, expireType, parseInt(throttlingPeriod));

    if (count > apiThrottlingLimit) {
      return { 'errCode': 403 };
    }
  } catch (e) {
    return { 'errCode': 500 };
  }
},
本文由作者按照 CC BY 4.0 进行授权