Nginx Worker进程间无传统锁同步,而是通过共享内存区+原子操作+乐观更新实现弱一致性协同;各Worker维护本地状态,周期性原子合并至共享zone,读多写少场景依赖只读映射与硬件原语保障性能。

Nginx 的 Worker 进程之间默认不共享内存,彼此独立运行,因此并不存在传统意义上的“进程间无锁化数据同步”机制。所谓“无锁化”,并非指多个 Worker 直接读写同一块内存并靠原子操作协调,而是通过设计规避跨进程并发修改的需要——核心思路是:让每个 Worker 自行维护本地状态,再借助共享内存(shared memory zones)+ 原子指令 + 乐观更新策略,实现**弱一致性、低冲突、免互斥锁**的数据协同。
共享内存区(Shared Memory Zone)是基础载体
Nginx 提供 zone 指令(如 limit_req_zone、limit_conn_zone、ssl_session_cache)在 master 进程中分配一块 mmap 映射的共享内存,所有 Worker 进程均可映射访问。这块内存由操作系统保证多进程可见性,但 Nginx 不直接在其上做加锁保护。
- 共享区结构由 Nginx 自定义(如红黑树、slab 分配器管理的 slot 数组),关键字段含原子计数器(
ngx_atomic_t) - Worker 仅对特定字段(如计数、时间戳)执行原子增减(
ngx_atomic_fetch_add)或 CAS(compare-and-swap)操作 - 不支持任意字段的原子读-改-写;复杂逻辑(如限速桶刷新)依赖“局部缓存 + 周期性同步”降低竞争
基于时间窗口与本地缓存的乐观更新
以 limit_req 模块为例:每个 Worker 不实时查共享 zone 中的精确请求数,而是维护一个本地滑动窗口计数器,并周期性(毫秒级)将本地增量合并到共享 zone 的原子计数器中。
- 请求到来时,Worker 先检查本地桶是否允许(快速路径,无锁)
- 若本地额度不足,才尝试用原子操作从共享 zone 扣减配额;失败则拒绝(CAS 冲突视为临时过载)
- 定时器定期将本地统计(如成功请求数)以原子方式累加进 zone 的全局统计字段,供监控或日志使用
只读共享与写隔离设计
多数场景下,Worker 仅需读取全局配置或只读状态(如 upstream server 状态、证书信息)。Nginx 将这类数据放在共享内存中,由 master 进程初始化/热更新,Worker 以只读方式映射,无需同步。
- upstream 的健康检查结果通过共享内存广播,Worker 定期轮询状态位,避免频繁锁竞争
- SSL session 缓存使用 slab + LRU 链表,插入/查找依赖原子指针操作(如
ngx_atomic_cmp_set更新头指针),而非互斥锁 - 真正需要强一致写的场景(如动态 upstream reload)交由 master 进程协调,Worker 通过信号或共享内存标志位感知变更
不依赖锁,但依赖内核与硬件原语
Nginx 的“无锁”是相对的:它放弃重量级互斥锁(mutex/semaphore),转而重度依赖底层支持:
- CPU 提供的原子指令(x86 的
LOCK XADD、LOCK CMPXCHG) - 操作系统提供的共享内存(
shm_open+mmap)和内存屏障(ngx_memory_barrier)保障可见性顺序 - 所有共享结构严格对齐、避免伪共享(false sharing),提升原子操作效率
这种模式牺牲了强一致性,换来了高并发下的低延迟与高吞吐——适合 Web Server 对“大致准确”即可的场景(如限流、统计、会话缓存),而非金融级事务系统。

















