核心是启用shared内存区并配置分桶锁,而非手动加锁;必须在http块顶层写ssl_session_cache shared:sslcache:10m,使所有worker映射同一posix共享内存,避免各进程私有缓存导致复用率趋零。

核心是用 shared 内存 + 分桶锁,而不是手动加锁或同步。Nginx 本身不产生“冲突”,错误配置(比如没用 shared)才导致各 worker 进程各自维护缓存,看起来像冲突。
必须启用 shared 内存区
在 http 块顶层写:
- 正确:`ssl_session_cache shared:sslcache:10m` —— master 创建 POSIX 共享内存,所有 worker 映射同一块地址空间
- 错误:`ssl_session_cache builtin:1024` 或只写 `ssl_session_cache 10m` —— 每个 worker 独占一份,无法共享会话,复用率趋近于 0
- 不能分散写在多个 server 块里;重复声明同名 zone 会被合并,但参数不一致可能引发未定义行为
合理设置大小与超时
缓存溢出比“冲突”更常见,表现为新建会话失败、日志报 could not allocate new session:
- 估算公式:
所需大小 ≈ QPS × ssl_session_timeout × 0.5KB(QPS 指新建 HTTPS 连接数,非总请求数) - 例如:峰值 1200 新连接/秒,timeout 设为 10 分钟(600 秒)→ 1200 × 600 × 0.5KB ≈ 360MB,建议配
shared:sslcache:512m - timeout 不宜过长(如 4h),现代客户端重连频繁,设 6–10 分钟更利于缓存周转
用 session ticket 降低共享内存压力
当 shared cache 承压或需跨多台 Nginx 复用时,ticket 是无状态替代方案:
- 开启:
ssl_session_tickets on; - 配密钥:
ssl_session_ticket_key /etc/nginx/ticket.key;(80 字节随机二进制) - 每 24–48 小时轮换一次 key(reload Nginx),保障前向安全性
- 注意:Chrome v119+ 默认禁用 Session ID 复用,此时 ticket 是主力,shared cache 可适当减小
验证是否真正生效
别只看配置语法,要观察实际行为:
- 用
openssl s_client -connect example.com:443 -reconnect连续请求,输出含Reused, SSL handshake has read 0 bytes才算复用成功 - 在日志或响应头中检查
$ssl_session_reused变量:值为.表示复用,0或空表示新建 - 运行
ipcs -m | grep nginx,确认有名称类似/nginx_sslcache的共享段,权限为rw-------











