一、为什么需要请求限流
想象一下,你开了一家网红奶茶店,突然有一天因为某个明星的推荐,顾客蜂拥而至。如果不控制人流,店员忙不过来,顾客等太久会走,甚至可能因为拥挤发生意外。服务器也是一样——当大量请求瞬间涌来时,如果没有限流机制,轻则响应变慢,重则直接崩溃。
Nginx 作为高性能的 Web 服务器和反向代理,提供了 limit_req 和 limit_conn 两个模块,能有效控制请求速率和连接数,避免服务器被突发流量冲垮。
二、limit_req:限制请求速率
limit_req 的核心思想是“漏桶算法”——想象一个底部有孔的桶,无论倒入多少水(请求),漏出的速度(处理速率)是恒定的。如果水太多,桶(缓冲区)满了就会溢出(拒绝请求)。
基础配置示例
http {
# 定义一个名为 "one" 的限流规则,速率 10 请求/秒,缓冲区 5 个请求
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
server {
location /api/ {
# 应用限流规则 "one",突发请求超过 5 个时直接拒绝
limit_req zone=one burst=5 nodelay;
proxy_pass http://backend;
}
}
}
关键参数解释:
limit_req_zone:定义共享内存区(zone=one:10m表示 10MB 内存),$binary_remote_addr按客户端 IP 限流。rate=10r/s:允许每秒 10 个请求。burst=5:允许瞬时超出 5 个请求(缓冲队列)。nodelay:不延迟处理缓冲的请求,直接尽快处理。
高级场景:多级限流
如果某些接口特别重要,可以分层限流:
http {
limit_req_zone $binary_remote_addr zone=low:10m rate=20r/s;
limit_req_zone $binary_remote_addr zone=high:10m rate=5r/s;
server {
location /api/common/ {
limit_req zone=low burst=10;
proxy_pass http://backend;
}
location /api/vip/ {
limit_req zone=high burst=2;
proxy_pass http://backend;
}
}
}
三、limit_conn:限制并发连接数
limit_conn 控制的是同一时刻的活跃连接数。比如你的服务器最多同时处理 1000 个连接,超过的直接拒绝。
基础配置示例
http {
# 定义名为 "addr" 的连接数限制区,每个 IP 最多 10 个连接
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
location /download/ {
# 每个 IP 限制 2 个并发连接
limit_conn addr 2;
limit_rate 100k; # 限速 100KB/s
alias /data/files/;
}
}
}
关键参数解释:
limit_conn_zone:类似limit_req_zone,但统计的是连接数。limit_conn addr 2:每个 IP 最多 2 个并发连接。limit_rate:可搭配限速,避免单个连接占满带宽。
四、实际应用与注意事项
1. 应用场景
- 防御 CC 攻击:限制单个 IP 的请求速率。
- 保护登录接口:防止暴力破解密码。
- 下载限速:避免带宽被单个用户耗尽。
2. 技术优缺点
优点:
- 配置简单,无需修改业务代码。
- 高性能,基于 Nginx 的异步事件驱动模型。
缺点:
- 分布式环境下需结合 Redis 等外部存储(Nginx 原生不支持)。
- 精确度不如令牌桶算法(如
ngx_http_limit_req_module的漏桶算法会有误差)。
3. 注意事项
- 内存分配:
zone的大小需根据预期 IP 数量调整(1MB 约存 1.6 万 IP)。 - 日志监控:被拒绝的请求会返回 503,建议监控日志调整阈值。
- 白名单设置:内网 IP 或爬虫可能需要豁免限流:
geo $limit {
default 1;
192.168.0.0/24 0; # 内网不限流
}
map $limit $limit_key {
0 ""; # 不限流
1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=api:10m rate=10r/s;
五、总结
Nginx 的 limit_req 和 limit_conn 是服务稳定的“守门人”,能有效避免突发流量导致的雪崩效应。配置时需结合实际业务调整速率和缓冲区大小,并通过监控持续优化。对于分布式系统,可考虑结合 Lua + Redis 或 OpenResty 实现更灵活的限流策略。
评论