必须配置upstream块内的zone指令(如zone backend_zone 64k),它通过共享内存使所有worker进程同步后端健康状态、连接数、哈希映射等运行时数据,且需搭配max_fails和fail_timeout才能触发故障标记,仅nginx 1.9.0+支持。

要让 Nginx 多个 worker 进程共享同一套 upstream 状态(比如谁健康、谁失败、当前连接数多少),核心就是用好 upstream 块里的 zone 指令。它不是可选项,而是打破进程隔离、实现状态实时同步的基础设施。
zone 是怎么打破数据孤岛的
默认情况下,每个 worker 进程各自维护一份 upstream 状态——彼此完全隔离。某个 worker 把后端标记为 down,其他 worker 一无所知,仍可能继续转发请求过去。加了 zone 才能改变这点:
- master 进程启动时调用 mmap() 分配一块物理内存,所有 worker 通过 fork 继承并直接映射访问
- 这块内存是零拷贝、无序列化、毫秒级响应的共享区域
- zone 名称(如
backend_zone)和大小(如64k)必须显式声明,不写就等于没开启共享 - 1.9.0 及以上版本才支持该机制
zone 里到底存了什么
这个共享内存区不只是记录“谁挂了”,而是承载整个 upstream 组的运行时上下文:
- 每个 server 的实时状态(up / down / unavail)、失败计数、上次失败时间
-
least_conn算法依赖的活跃连接数 -
hash和ip_hash的会话绑定映射(确保不同 worker 对同一 IP 总选同一台后端) -
slow_start阶段的权重爬升进度 - NGINX Plus 的 API(如
/api/6/http/upstreams/backend)读取的正是这里的数据
必须配合的基础配置才能真正生效
光有 zone 不足以自动识别故障或触发负载逻辑,还需搭配基础参数:
- 必须设置
max_fails和fail_timeout,否则即使加了 zone,Nginx 也不会主动标记节点为不可用 - 若 upstream 中只有一个 server,这两个参数会被忽略,该节点永远不会被标记为 down
-
least_conn、ip_hash等算法只有在 zone 存在时,才能保证所有 worker 计算结果一致 - 多个 upstream 块可以共用同一个 zone 名称,但 size 只需在第一个里指定
配置示例与关键提醒
一个典型可用的 upstream 块如下:
upstream backend {
zone backend_zone 64k;
least_conn;
server 10.0.1.10:8080 max_fails=3 fail_timeout=30s;
server 10.0.1.11:8080 max_fails=3 fail_timeout=30s;
}
注意点:
- size 要足够容纳所有 server 条目及其状态,太小会导致 warning 甚至功能异常
- reload 操作会清空 zone 内容(除非配置未变更且使用特定 reload 行为)
- zone 不提供强一致性锁机制,而是靠“写隔离 + 乐观更新”降低竞争,适合状态聚合类场景











