必须显式配置 upstream 块内的 zone 指令(如 zone backend_zone 64k),它通过共享内存使所有 worker 进程同步后端状态(健康状况、连接数、ip 哈希映射等);仅配置 zone 不足,还需为每个 server 设置 max_fails 和 fail_timeout 才能触发自动故障标记。

要让 Nginx 多个 worker 进程真正共享 upstream 后端的运行状态(比如谁健康、连接数多少、IP 哈希映射是否一致),必须显式配置 zone 指令。它不是增强项,而是打通进程隔离的唯一方式。
zone 是跨 worker 共享状态的前提
默认情况下,每个 worker 进程各自维护一份 upstream 状态:一个 worker 把某台后端标记为 down,其他 worker 完全不知情,仍可能转发请求过去,造成失败或超时。zone 指令启用共享内存,让所有 worker 读写同一块区域:
- 必须写在
upstream块内部,格式为:zone name size;(如zone backend_zone 64k;) -
name是自定义标识符,不能含点号或特殊字符;size要预估足够,64k 可支撑约 10–20 个后端,节点多可设为1m - Nginx 1.9.0+ 才支持;Windows 原生版不支持,会报
"zone" directive is not supported on this platform
zone 共享内存里实际存什么
这块内存不只是记“up/down”,而是承载整个 upstream 组的核心运行时数据:
- 每台
server的实时状态(up/down/unavail)、失败次数、上次失败时间 -
least_conn所需的各后端当前活跃连接数(确保所有 worker 计算结果一致) -
ip_hash或hash $arg_key consistent的客户端到后端的绑定映射 -
slow_start阶段中权重的动态爬升进度
光有 zone 不够,必须搭配健康机制
zone 提供存储载体,但不会自动判断故障。要真正触发状态变更,还需基础健康参数:
- 每个
server行必须设置max_fails和fail_timeout(如max_fails=3 fail_timeout=30s) - 若 upstream 中只有一个 server,这两个参数会被忽略,该节点永不标记为 down
-
proxy_next_upstream的重试行为也依赖 zone 中的实时状态,建议按地域调优超时值
验证是否生效的实用方法
配置完成后,别只看语法是否通过,要实测状态是否真被共享:
- 在日志中加入
$pid和$upstream_addr,用同一客户端 IP 发起多次请求 - 观察不同
$pid(即不同 worker)下,$upstream_addr是否始终指向同一台后端(尤其对ip_hash) - 手动停掉一台后端,观察所有 worker 是否在
fail_timeout后同步将其标记为down,不再转发 - 修改 zone 配置后务必执行
nginx -s reload,避免新旧 worker 争抢共享内存











