常见限流算法
- 固定窗口算法
将时间划分为固定窗口,统计窗口内请求数,超过阈值则限流。
优点:实现简单,内存占用低。
缺点:窗口切换时可能触发双倍突发(如窗口最后 1 秒和新窗口前 1 秒各 100 次)。
应用场景:对精度要求不高的轻量级限流。 -
滑动窗口算法
将时间窗口划分为多个子窗口,统计滑动时间范围内的请求数。
比如将 1 分钟分为 6 个 10 秒的子窗口,统计最近 6 个子窗口的总和。
优点:解决临界问题,限流更平滑。
缺点:实现复杂度较高,需维护多个子窗口数据。
应用场景:高并发且对精度要求高的场景。 -
漏桶算法
请求进入漏桶后,以固定速率流出,超出容量的请求被丢弃。
优点:有效削峰填谷,保证稳定输出。
缺点:无法利用突发流量,可能降低资源利用率。
应用场景:严格限制平均速率的场景(如 API 接口限流)。 -
令牌桶算法
以固定速率生成令牌存入桶中,请求需消耗令牌才能通过,允许突发。
优点:支持突发流量,同时控制平均速率。
缺点:实现复杂度高于固定窗口。
应用场景:允许瞬时高峰但需控制整体速率的场景(如 CDN 加速)。
nginx 限流模块
- ngx_http_limit_conn_module
限制同一客户端的并发连接数,保护服务器资源。
http {
limit_conn_zone $binary_remote_addr zone=addr:10m; # 按IP分组,共享内存10MB
server {
location / {
limit_conn addr 2; # 每个IP最多2个并发连接
proxy_pass http://backend;
}
}
}
- ngx_http_limit_req_module
基于漏桶算法限制请求速率,支持突发请求缓冲。
http {
limit_req_zone $binary_remote_addr zone=req:10m rate=10r/m; # 每分钟10请求
server {
location /api {
limit_req zone=req burst=5 nodelay; # 允许5个突发请求
proxy_pass http://api_backend;
}
}
}
- ngx_http_limit_rate_module
限制客户端下载速度
location /downloads {
limit_rate 200k; # 200KB/s
alias /data/downloads;
}
限流模块还有很多,可以自行查阅AI。