nginx全局限流需依赖shared memory zone实现,与轮询负载均衡分层协作:limit_req_zone在http块定义共享区,用$binary_remote_addr哈希确保客户端统一限流,location中limit_req须置于proxy_pass前,限流生效后才轮询调度后端。

全局限流与轮询负载均衡可以协同工作,但需明确:Nginx 本身不支持“跨 worker 进程的全局共享限流计数器”,所以所谓“全局限流”必须依赖 shared memory zone(共享内存区),而该机制天然支持多 worker 并发访问,是实现真正全局限流的基础。
核心前提:用 limit_req_zone 定义共享限流区域
轮询和限流不是互斥配置,而是分层协作——upstream 负责请求分发,limit_req_zone 负责速率控制。关键在于 zone 必须定义在 http 块顶层,并使用 $binary_remote_addr 或其他稳定键做哈希,确保同一客户端被统一限流:
- zone 名称(如 mylimit)需唯一,大小按预期并发请求数预估(例如 10m 可存储约 16 万个键值对)
- rate 设为每秒请求数(如 10r/s),支持带 burst 的漏桶模型(如 burst=20 nodelay)
- 不要用 $remote_addr,IPv4 映射可能不一致;$binary_remote_addr 更紧凑、更可靠
在 location 中启用限流并代理到轮询 upstream
限流动作必须放在 proxy_pass 之前,否则请求已发往后端才限流就失去意义。典型结构如下:
- 先 match 请求路径(如 location /api/)
- 立即应用 limit_req,引用前面定义的 zone
- 再设置 proxy_pass 指向轮询 upstream(如 http://backend)
- 保留必要头信息(Host、X-Real-IP 等),避免后端无法识别原始请求
示例片段:
http {
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=5r/s;
upstream backend {
server 192.168.1.101:8080;
server 192.168.1.102:8080;
server 192.168.1.103:8080;
}
server {
listen 80;
location /api/ {
limit_req zone=mylimit burst=10 nodelay;
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
注意轮询与限流的配合边界
限流发生在 Nginx 接收请求时,早于轮询调度。这意味着:
- 限流是“前端守门员”,轮询是“后端调度员”,二者职责分明
- 即使某台后端临时不可用(max_fails 触发剔除),限流仍持续生效,不会因轮询跳过而绕过限制
- 若需对不同 upstream 区分限流(如 /v1/ 和 /v2/ 走不同集群),应定义多个 zone 并分别绑定
- burst 队列在 Nginx 内存中排队,不占用后端连接;nodelay 表示允许突发流量直接通过(不延迟),但超限仍会返回 503
验证是否真正协同生效
可分两步验证:
- 用 ab 或 wrk 对单个接口压测(如 wrk -t2 -c50 -d10s http://nginx-ip/api/test),观察响应状态码中 503 出现比例是否符合限流设定
- 同时检查各后端 access log,确认被放行的请求仍保持轮询规律(如 IP 日志交替出现),说明限流未破坏调度逻辑











