Nginx限流配置(limit_req)
NGINX 提供 limit_req 和 limit_conn 模块实现请求限流,保护后端不被过量请求压垮。
limit_req_zone 定义
共享内存区域
nginx
http {
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login_limit:5m rate=3r/m;
}
$binary_remote_addr— 按客户端 IP 限流(比$remote_addr节省内存)zone— 共享内存区域名称和大小rate— 请求速率(r/s 或 r/m)
10MB 区域可存储约 160000 个 IP 地址的状态。rate 定义的是长期平均速率。
limit_req 使用
基本限流
nginx
server {
location /api/ {
limit_req zone=api_limit;
proxy_pass http://backend;
}
}
默认 burst=0,超出速率的请求直接返回 503。
burst 缓冲
nginx
location /api/ {
limit_req zone=api_limit burst=20;
proxy_pass http://backend;
}
burst=20— 最多 20 个请求排队等待处理- 超出 burst 的请求返回 503
- 默认 burst 中的请求按 rate 匀速处理
nodelay 立即处理
nginx
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://backend;
}
nodelay让 burst 中的请求立即处理而非排队。效果近似令牌桶算法。
不同路径不同策略
分级限流
nginx
http {
limit_req_zone $binary_remote_addr zone=general:10m rate=30r/s;
limit_req_zone $binary_remote_addr zone=login:5m rate=5r/m;
}
server {
# 一般 API
location /api/ {
limit_req zone=general burst=50 nodelay;
}
# 登录接口严格限流
location /api/login {
limit_req zone=login burst=3 nodelay;
}
# 搜索接口中等限流
location /api/search {
limit_req zone=general burst=10 nodelay;
}
}
限流响应定制
自定义 503 页面
nginx
limit_req_status 429; # 使用 429 Too Many Requests
server {
error_page 429 /too_many_requests.html;
location = /too_many_requests.html {
internal;
default_type application/json;
return 429 '{"error":"rate_limit_exceeded","retry_after":1}';
}
}
默认返回 503。使用
limit_req_status改为 429 更符合 REST 规范。
limit_conn 并发限制
限制并发连接数
nginx
http {
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
}
server {
location /download/ {
limit_conn conn_limit 5; # 每个 IP 最多 5 个并发连接
}
}
limit_conn限制同一 key 的并发 TCP 连接数。适合限制大文件下载等场景。
日志记录
记录被限流的请求
nginx
http {
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_req_log_level warn;
}
默认日志级别为
error。改为warn或info可记录被限流的请求。
要点总结
limit_req_zone定义共享内存区域和速率limit_req应用限流规则到 locationburst定义排队容量,nodelay立即处理而非排队$binary_remote_addr比$remote_addr更节省内存limit_req_status 429返回更语义化的状态码limit_conn限制并发连接数而非请求速率- 不同接口使用不同限流 zone 实现分级限流
📝 发现内容有误?点击此处直接编辑