根本原因是重复高开销计算,优化核心是全局会话复用:ssl_session_cache必须置于http块顶层,配合4h超时、tls 1.3、ocsp装订及session tickets兜底。

高并发下 HTTPS 握手变慢、CPU 升高,根本原因不是连接数多,而是大量重复做密钥交换、证书验证等高开销计算。优化核心是:让绝大多数连接复用已有会话,把完整握手压到最低频次,并确保复用机制跨 worker 进程真正生效。
必须在 http 块顶层配置共享会话缓存
ssl_session_cache 只有写在 http { } 最外层才有效。写在 server 或 location 里,每个 worker 自建缓存,无法共享,复用率趋近于零。
- 正确写法:ssl_session_cache shared:SSL:20m;(中小规模可从 10m 起步,CDN 源站或网关建议 20m–50m)
- 超时设为 4h(14400 秒):默认 5 分钟太短,移动端切后台再唤醒基本错过复用窗口;4 小时兼顾内存与真实用户行为周期
- 禁用 builtin 缓存:如 builtin:1000 是每个 worker 独立小缓存,高并发下命中率极低
启用 Session Tickets 做无状态兜底
仅靠共享缓存扛不住突发流量——缓存满后新连接被迫全握手,CPU 和延迟同步飙升。Session Tickets 把部分状态交给客户端,天然支持跨进程、跨重启、甚至跨机器复用。
- 开启:ssl_session_tickets on;
- 指定密钥文件:ssl_session_ticket_key /etc/nginx/ssl/ticket.key;(用 openssl rand 48 > ticket.key 生成二进制密钥)
- 密钥建议每月轮换:生成新 key 后 reload Nginx,旧票据仍可解密,新连接自动使用新密钥
精简协议栈,压低单次握手开销
TLS 1.3 不只是“更快”,它砍掉冗余消息和弱算法协商路径,CPU 消耗比 TLS 1.2 低 30%~50%;配合高效密码套件,能显著缩短单次协商时间。
- 明确启用:ssl_protocols TLSv1.2 TLSv1.3;(禁用 TLSv1.0/v1.1)
- 聚焦 ECDHE+AEAD 套件:ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
- 服务端主导协商:ssl_prefer_server_ciphers on;
- 限定椭圆曲线与签名算法,跳过冷门选项:ssl_conf_command Curves X25519:secp256r1; 和 ssl_conf_command SignatureAlgorithms ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256:rsa_pkcs1_sha256;
配合 OCSP Stapling 加速证书验证
客户端直连 CA 查询吊销状态,常因 DNS、网络抖动或防火墙卡住,拖慢 150–300ms。Nginx 主动装订响应,可绕过这一步。
- 四项配置缺一不可(全部写在 443 server 块内):ssl_stapling on;、ssl_stapling_verify on;、ssl_trusted_certificate /path/to/full-chain-trusted.pem;(中间 CA + 根 CA 拼接)、resolver 8.8.8.8 1.1.1.1 valid=300s; resolver_timeout 5s;
- 证书必须含 Authority Information Access 扩展,服务器时间误差不能超 ±5 分钟
验证是否真正落地生效
配置写对 ≠ 效果达成,需实测确认:
- 检查位置:nginx -T | grep "ssl_session_cache.*shared",输出应唯一且位于 http { 后、server { 前
- 日志中加入 $ssl_session_reused,统计 24 小时内 “r”(reused)占比;长期低于 70% 说明缓存偏小或超时过短
- 终端测试:openssl s_client -connect example.com:443 -reconnect -servername example.com 2>/dev/null | grep "Reused",多次执行出现 “Reused, TLSv1.3” 表示成功











