nginx通过共享内存实现跨worker状态共享,依赖mmap+fork继承与cow机制,以偏移量寻址;上层模块(如limit_req、upstream zone、proxy_cache)配合原子操作或ngx_shmtx_t锁保障并发安全。

Nginx 通过共享内存实现状态共享,核心在于让所有 worker 进程读写同一块物理内存区域,而非各自维护独立副本。这种机制不依赖进程间消息传递,而是靠底层 mmap + fork 的继承特性与上层结构化管理协同完成。
共享内存的创建与继承
master 进程启动时调用 mmap(),指定 MAP_SHARED | MAP_ANONYMOUS 标志分配一块匿名内存,内容初始化为 0。随后 fork 出多个 worker 进程——由于 Linux 写时复制(COW)机制,这些子进程在只读访问时共享同一物理页;即使有写操作,也仅对修改页做私有拷贝,不影响其他 worker 对原始共享区的读取。
- 各 worker 中虚拟地址可能不同,Nginx 内部统一用相对偏移(offset)定位字段,避免硬编码指针
- 共享内存生命周期由 master 管理,worker 退出不释放,模块卸载前需确保无活跃访问
状态数据如何组织与访问
共享内存本身是一段裸内存,真正支撑状态共享的是上层模块定义的数据结构和访问协议:
-
限流模块(
limit_req/limit_conn):将令牌桶计数器或连接数存于共享内存中,配合ngx_shmtx_t锁保障写安全,实现全实例统一速率控制 -
上游健康状态(
upstream zone):启用zone backend_zone 64k;后,所有 worker 共享后端节点的 up/down 状态、失败次数、当前连接数、ip_hash 映射关系等,避免状态隔离导致误发请求 -
缓存元数据(
proxy_cache):key 索引、过期时间、缓存状态等存于共享内存,减少磁盘查找频次;实际响应体仍落盘或走独立内存池 -
运行指标统计(
stub_status):使用ngx_atomic_t类型变量(如活跃连接数、已接受请求数),各 worker 原子累加,无需锁即可安全更新
安全写入的关键保障
读操作天然并发安全,但写操作必须互斥。Nginx 提供两类轻量级同步手段:
-
原子操作:适用于整数增减、位图翻转等简单场景,如
ngx_atomic_fetch_add()、ngx_atomic_cmp_set() -
共享内存互斥锁(
ngx_shmtx_t):基于自旋锁语义 + CAS 指令实现,lock 字段是一个共享内存中的uint32_t变量(0 表示空闲,1 表示已加锁),临界区必须极短(如更新计数器、增删连接节点)
在配置与 Lua 中直接使用
面向网关类场景,最常用的是 lua_shared_dict 指令:
- 在
http块中声明:lua_shared_dict rate_limit 10m; - Lua 脚本中调用:
shared:set(key, val, ttl)、shared:incr(key, delta)、shared:get_set(key, newval),这些均为原子操作,底层自动加锁 - key 最长 255 字节,建议对长标识哈希压缩;value 支持 number/string 原生存储,简单 table 可序列化,嵌套过深会失败











