共享内存区是跨Worker协同的底层基础:Nginx主进程预分配shared:SSL:10m等POSIX共享内存,所有Worker映射共址访问,通过自旋锁保护哈希表实现会话复用,无同步广播;Windows因缺乏POSIX支持仅能回退builtin模式。

共享内存区是跨 Worker 协同的底层基础
Nginx 多进程模型中,Worker 进程彼此独立、无共享地址空间。要实现 SSL 会话缓存的跨进程复用,必须依赖操作系统级的共享内存(Shared Memory)。Nginx 通过 POSIX 共享内存(Linux/macOS)或 Win32 共享内存对象(Windows 上受限)在主进程启动时预先分配一块固定大小的内存区域,并由所有 Worker 进程映射访问。配置中的 shared:SSL:10m 正是告诉 Nginx:创建一个名为 SSL、容量 10MB 的全局共享内存区。该区域由主进程统一管理,Worker 进程仅以只读-写方式操作其中的数据结构,不自行分配或释放内存。
缓存条目不是“复制”,而是“共址访问”
每个 TLS 握手产生的会话(Session ID 或 PSK 标识)被序列化后,直接写入共享内存区的哈希表槽位中。所有 Worker 进程使用同一套哈希函数、同一张桶数组、同一组锁机制来定位和操作这些条目。这意味着:
- Worker A 缓存的会话,Worker B 下次收到带相同 Session ID 的 Client Hello 时,可直接命中并复用
- 不存在“同步广播”或“后台复制”行为——没有网络传输,也没有进程间消息通信
- 并发写入由轻量级自旋锁(spinlock)保护,避免多 Worker 同时修改同一槽位导致数据损坏
Windows 是特例:builtin 模式本质是“伪共享”
Windows 官方二进制版缺乏对 POSIX shm_open() 的完整支持,无法构建跨进程共享内存区。因此 ssl_session_cache shared 在 Windows 上不可用,只能退回到 builtin 模式。此时:
审查 Remix v2 代码中的 v1 形态 meta 导出(v2 中为破坏性变更),cookie 安全漏洞(httpOnly、secure、密钥轮换),认证门位于错误层级,以及其他
- 每个 Worker 进程各自维护一份 OpenSSL 内置缓存(基于 LRU 链表),互不感知、互不同步
- 客户端若被负载均衡到不同 Worker,即使 Session ID 相同,也大概率触发全握手
- 配置
builtin:1024仅表示单个 Worker 最多存 1024 条,总容量 = Worker 数 × 1024,但复用率随 Worker 数增加而下降
这也是为什么 Windows 生产环境强烈建议设 worker_processes 1 或迁移到 WSL2/Linux 容器——只有单 Worker 才能发挥 builtin 缓存的实际价值。
超时与淘汰由主进程协调,非定时轮询
共享内存中的会话条目带有时间戳,但过期清理并非由各 Worker 主动扫描。Nginx 采用惰性+周期双重机制:
- 每次查找会话时,先校验时间戳是否过期;若过期,立即丢弃并返回未命中
- 主进程每 60 秒触发一次
ngx_ssl_expire_sessions调用,遍历共享内存哈希表,批量回收超时条目,释放空间 - 当新会话写入时发现空间不足,会优先驱逐最久未使用的有效条目(LRU),而非等待超时
这种设计避免了 Worker 频繁争抢清理锁,也防止因某 Worker 长期空闲导致僵尸会话堆积。

















