Nginx Worker 进程间默认不通信,因采用无状态多进程设计,依赖Master统一调度及共享内存或外部存储实现数据同步。

Nginx 的 Worker 进程之间默认不共享内存、不直接通信,也没有内置的跨进程数据同步机制。它的设计哲学是“无状态多进程 + 共享资源隔离”,通信与同步需靠外部手段或特定模块实现,而非内核级 IPC 或消息总线。
Worker 进程为何不直接通信?
Nginx 采用 主从(Master-Worker)模型:Master 进程负责管理(启动、平滑重启、信号处理),Worker 进程彼此独立、完全对等,每个 Worker 绑定一个 CPU 核心,处理客户端连接。这种设计避免锁竞争、简化并发模型,也意味着:
- Worker 间没有共享堆内存,无法通过指针或变量直接读写对方数据
- 没有内置消息队列、管道或 socket 对等通信通道
- 所有“协同”行为(如 reload、退出)均由 Master 进程统一调度,通过信号(SIGUSR2、SIGQUIT 等)间接协调
实际可用的跨 Worker 数据同步方式
当业务需要共享状态(如限流计数、黑名单、缓存失效),必须引入外部机制。常见且生产可行的方式包括:
-
共享内存区(Shared Memory Zone):Nginx 原生支持(via
ngx_http_limit_req_module,ngx_http_limit_conn_module, 或lua_shared_dict)。多个 Worker 可读写同一块由 Master 分配并映射的内存区域,底层基于mmap(POSIX)或shm_open,配合原子操作(如 CAS)和自旋锁保证基本一致性。注意:仅限简单键值(字符串/数字),不支持复杂结构或事务 - 外部存储系统:Redis、etcd、Consul 等。Worker 各自发起网络请求读写,依赖服务端一致性协议(如 Redis 的单线程+命令串行、etcd 的 Raft)。延迟高但可靠,适合跨机器部署场景
-
文件系统 + 原子操作:极少数场景下用临时文件(如
touch /tmp/nginx_reload_flag)配合 inotify 或轮询,但性能差、易出错,不推荐用于高频同步 -
第三方模块扩展:如
nginx-module-vts(状态监控)、nginx-lua-module结合resty.lock实现分布式锁,本质仍是封装上述外部机制
Master 如何协调 Worker 行为?
Worker 本身不通信,但 Master 可通过系统信号和共享内存控制其生命周期与配置加载:
-
kill -USR2 $master_pid:触发平滑升级——Master fork 新 Worker,加载新二进制和配置;旧 Worker 处理完已有连接后退出 -
kill -HUP $master_pid:重载配置——Master 重新解析配置,创建新 Worker,逐步关闭旧 Worker(graceful shutdown) -
kill -WINCH $master_pid:仅关闭 Worker(不退出 Master),常用于降级维护 - 配置热更新时,Master 将解析后的结构体(如 upstream、limit_req zone)通过
shm映射到所有 Worker 地址空间,Worker 在运行时按需访问,无需进程间传递
为什么不用 epoll_wait 跨进程通知?
epoll 是进程级的 I/O 多路复用机制,每个 Worker 拥有自己独立的 epoll fd 和事件循环。即使监听同一端口(SO_REUSEPORT 已启用),内核也会将连接分发到不同 Worker 的 epoll 实例中,epoll 事件不会跨进程广播。因此无法用 epoll 作为 Worker 间的通知通道——这不是 Nginx 的限制,而是 Linux I/O 模型本身的约束。
不复杂但容易忽略:Nginx 的“高并发”优势正源于 Worker 的彻底隔离;所谓“同步”,其实是让每个 Worker 在各自上下文中做出一致决策,而不是实时交换数据。真正需要强一致性的场景,应交给专业中间件处理,而非在 Web 服务器层强行缝合。










