ssl握手是https最耗cpu环节,高并发下易形成“ssl热点”;优化核心是减少握手次数、缩短单次耗时、分散会话压力,而非调整调度算法。

SSL 握手是 HTTPS 请求中最耗 CPU 的环节,尤其在高并发场景下,频繁的完整握手会让单个 worker 进程的 CPU 使用率飙升,形成“SSL 热点”。这不是负载不均导致的调度问题,而是加密运算集中在握手阶段引发的计算瓶颈。优化核心不是改调度算法,而是减少握手次数、缩短单次握手耗时、分散会话状态压力。
识别 SSL CPU 热点的真实信号
别只看 top 里 nginx worker 占 CPU 高——要确认是不是 SSL 引起的:
- 检查日志中 $ssl_session_reused 变量:长期低于 60%,说明会话复用率差,大量请求被迫走完整握手
- 执行 nginx -T | grep "ssl_session_cache.*shared":输出应仅一行,且位于
http {块内;若没输出或出现在多个server块里,缓存未生效或被隔离 - 运行 free -m 查看 shared 内存:缓存区使用率持续接近 100%,大概率已溢出,新会话挤掉旧会话,复用率断崖下跌
- 观察 openssl s_client -connect example.com:443 -reconnect 输出:若多次连接 Session-ID 不同、或反复出现
Reused: No,说明缓存未命中
强制精简 TLS 协商路径,降低单次握手开销
客户端发来的支持列表越杂,Nginx 在握手初期匹配算法、曲线、签名组合的 CPU 开销越大。用 ssl_conf_command 直接干预 OpenSSL 底层行为,跳过冗余遍历:
-
限定密钥交换曲线:
ssl_conf_command Curves X25519:secp256r1;—— 排除 secp384r1/secp521r1 等高开销曲线,X25519 运算快、兼容广 -
收紧签名算法:
ssl_conf_command SignatureAlgorithms ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256:rsa_pkcs1_sha256;—— 剔除所有 sha1、弱填充及冷门组合 - 该指令需 Nginx ≥ 1.19.4 + OpenSSL ≥ 1.1.1,且必须放在
ssl_certificate之后,否则无效
构建两级会话复用体系,避免 shared 缓存成为单点瓶颈
只靠 ssl_session_cache shared 容易因大小不足或 worker 分布不均造成热点。应叠加 session ticket 实现无状态复用:
-
共享缓存设合理大小:小站起步用
shared:SSL:5m,中高流量用10m–20m(1M ≈ 4000 会话),写在http块顶层,全局唯一 -
必须开启 ticket 机制:
ssl_session_tickets on;+ssl_session_ticket_key /etc/nginx/ssl/ticket.key; -
定期轮换 ticket 密钥:每月用
openssl rand 48 > ticket.key生成新密钥并 reload,既保障安全又避免单密钥长期失效导致复用率下降 - ticket 天然跨 worker、跨重启,弥补 shared 缓存的局限,对 Android 4.x 等旧客户端也更友好
OCSP Stapling 配置不当也会间接推高 CPU 负载
OCSP 查询若卡在 DNS 解析或响应超时,worker 进程会在握手阶段阻塞等待,引发上下文频繁切换和 wait 时间上升,表现为 CPU 利用率虚高:
-
指定稳定快速的 resolver:
resolver 1.1.1.1 8.8.8.8 valid=300s;—— 避免用系统默认 DNS 或不可靠上游 -
设置明确超时:
resolver_timeout 5s;—— 防止长时间挂起 -
启用并验证 stapling:
ssl_stapling on; ssl_stapling_verify on;,确保证书链完整且 OCSP 响应可验证











