应优先使用 shared 缓存而非 builtin;大小须按「每秒新会话数 × 超时时间 × 0.5KB」精确计算,如 800 新会话/秒、4h 超时需约 6MB,起步配 10m;必须唯一配置在 http 块顶层,否则无效或引发未定义行为。

直接用 shared 缓存,别依赖 builtin;大小按「每秒新会话数 × 超时时间 × 0.5KB」算,不是拍脑袋填 10m;必须只在 http 块顶层配一次,否则白配。
为什么 builtin 几乎没用
builtin 是每个 worker 进程私有的缓存,比如 builtin:1000 表示单个 worker 最多存 1000 条会话。但客户端重连不固定落到同一个 worker,尤其开启 SO_REUSEPORT 或关闭 accept_mutex 后,分发更随机。结果就是 A worker 缓存了会话,B worker 收到重连却查不到,只能走完整握手。
- 除非你明确做了 sticky session(比如用
worker_cpu_affinity+ 负载均衡器绑定),否则 builtin 对复用率提升基本为零 - 它响应快,但解决不了跨进程一致性问题——这正是
shared存在的意义 - 调试时可临时加
builtin:500辅助验证 handshake 流程,上线必须靠shared
shared 缓存大小怎么算才准
公式是:cache_size ≈ new_sessions_per_sec × timeout_sec × 0.5KB。其中:
-
new_sessions_per_sec不是 QPS,而是每秒新建 TLS 会话数,可通过压测 + 日志中$ssl_session_reused字段统计得出(值为 0 表示全握手) -
timeout_sec对应ssl_session_timeout,建议设为 4h(14400 秒),太短会导致复用率断崖下跌 - 0.5KB 是保守估算值,实际单条占用在 256–512 字节之间,证书链长、启用 OCSP Stapling 会略高
举例:实测峰值每秒新建 800 个会话,超时设为 4h,则理论需约 6MB,起步建议配 shared:SSL:10m;QPS ≥ 500 的 API 网关或前端资源服务,直接上 20m 更稳妥。
怎么确认配置生效且没溢出
溢出不会报错,但会静默退化为全握手——表现为 CPU 突升、延迟变高、$ssl_session_reused 日志中 .0 比例明显上升。
- 运行
nginx -T | grep "ssl_session_cache.*shared",输出应仅一行,且位置在http {之后、任何server {之前 - 观察
$ssl_session_reused变量统计:长期低于 60%,大概率是缓存太小被频繁淘汰 - 用
free -m查 shared 内存使用率:长期低于 20%,说明分配过量;接近 100% 则可能已溢出 - 配合
ssl_session_tickets on和轮换的ticket.key,作为无状态补充,降低对 shared 的压力
必须注意的配置细节
ssl_session_cache 必须统一写在 http 块顶层,且只出现一次。多个 server 块里重复写同名 shared 配置,Nginx 会合并,但存在风险:
- 若某
server块误写成shared:SSL:5m,reload 时可能触发未定义行为 - Worker 进程只认主进程初始化的那一份共享区,server 级配置无法改变其生命周期或锁机制
- 真正生效的只有 http 块中首次声明的那一条;其余同名声明会被忽略或覆盖,不报错也不提示



















