限流介绍
请求限流用于控制网络请求和传输量的技术, 用于健全node服务应用, 通常会开启接口速率限制,来控制一定周期内最大的请求量,用于保护服务应用免遭恶意请求和流量攻击
限流常用算法
1. 固定窗口算法
a. 介绍
固定窗口算法: 在固定的时间范围内,窗口大小指允许通过最大请数。 也就是一段时间内最大允许请求量; 也就是在一个周期开始的时候,计数器清零,每个请求都将被计数,若计数达到上限,则不会再响应多余的请求,直到进入下一个周期
b. 代码实现
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
| import { fixedWindow } from "./middleware/fixedWindow.js"; app.use(fixedWindow);
import Redis from 'ioredis'
const FIX_WINDOW_SIZE = 60; const FIX_WINDOW_MAX_REQUEST = 100;
const redisClient = new Redis(6379);
export const fixedWindow = async (ctx, next) => { const redisKey = `${ctx.ip}:ratelimit`; const curCount = await redisClient.get(redisKey); if (!curCount) { await redisClient.setex(redisKey, FIX_WINDOW_SIZE, 1); next(); return; } if (Number(curCount) < FIX_WINDOW_MAX_REQUEST) { await redisClient.incr(redisKey); next(); } else { ctx.status = 429; ctx.body = "you have too many requests"; } };
|
c. 缺点

**不平滑, 在2个窗口之间容易被攻击,图中9:03 - 9:04实际请求数已经超过了设置的最大上限**
2. 滑动窗口算法
a. 介绍

滑动窗口算法:这种算法是对固定窗口算法一种优化(这种算法一定范围内只有一个窗口), 在一个周期范围内有多个窗口进行计数, 窗口越多, 算法就越平滑。
b. 代码实现
3. 漏桶算法
a. 介绍

漏桶算法:api请求过程类比漏桶加水,漏桶流入速度不做限制, 而是限制漏桶流出速度; 当流入速度大于流出速度, 随着桶中水平面不断上涨, 漏桶水流就会溢出,
b. 代码实现
4. 令牌桶算法
a. 介绍

令牌桶算法:定义了一个集合(也就是桶), 集合中容纳一定数量的令牌, api被请求一次消耗一个令牌; 如集合中没有令牌则不允许请求通过, 集合通过一定的速率去生成新的令牌, 以此达到限流的作用。
b. 代码实现
redis-cell模块
nginx 限制IP的连接和并发达到限流
参考文章1
参考文章2