nginx https握手慢、cpu高的本质是重复高开销计算,优化核心是全局会话复用:ssl_session_cache须置于http块顶层,配合4h超时、tls 1.3、ocsp装订及合理负载策略。

Nginx 在高负载下 HTTPS 握手变慢、CPU 升高,本质不是连接数太多,而是每次握手都在重复做高开销计算。优化核心是:让大多数连接复用已有会话,把完整握手压缩到最低频次,并确保复用机制真正跨进程生效。
确保 TLS 会话复用真正全局可用
复用失效,90% 的优化都白做。关键不在 server 块里加几行配置,而在 http 块顶层构建统一上下文。
-
ssl_session_cache必须写在http { }最外层,格式为:ssl_session_cache shared:SSL:20m;
写在
server或location里 → 各 worker 自建缓存 → 无法共享 → 复用率趋近于 0 -
ssl_session_timeout设为4h(14400 秒):- 默认 5 分钟太短,移动端切后台再唤醒、HTTP/1.1 短连接场景基本错过复用窗口
- 4 小时兼顾内存占用与真实用户行为周期
- 启用
ssl_session_tickets on;并配密钥:ssl_session_ticket_key /etc/nginx/ssl/ticket.key;
客户端携带票据,服务端无需查表,突发流量下兜底有效;密钥建议每月轮换
用 TLS 1.3 + 精简密码套件压低单次开销
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 与证书链加速验证
客户端直连 OCSP 服务器验证证书,常因 DNS 查询或网络抖动卡住握手。Nginx 主动装订响应,可省掉 50%+ 验证延迟。
- 开启 stapling 并严格校验:
ssl_stapling on; ssl_stapling_verify on;
- 提供完整可信链(不只是域名证书):
ssl_trusted_certificate /path/to/fullchain.pem;
- 指定稳定 DNS 解析器,避免系统 resolver 不可靠:
resolver 8.8.8.8 1.1.1.1 valid=300s; resolver_timeout 5s;
调整负载策略,避免复用请求扎堆
ip_hash 看似稳定,实则把复用请求长期绑定到同一后端,导致部分节点 CPU 持续高位,其他节点闲置。
- 改用动态策略,如
least_conn或least_time:upstream backend { least_conn; server 10.0.0.1:443; server 10.0.0.2:443; } - 若需会话保持,改用
hash $remote_addr consistent;(一致性哈希),比 ip_hash 更均衡 - 后端也走 HTTPS(如微服务间代理)时,别忘了:
proxy_ssl_session_reuse on;
验证是否生效很简单:
-
nginx -T | grep ssl_session_cache确认输出位于http块内 - 日志中加
$ssl_session_reused字段,统计 24 小时内r(reused)占比,长期低于 60% 就得调大缓存或延长 timeout - 用
openssl s_client -connect example.com:443 -reconnect连 5 次,看到多次Reused, TLSv1.3才算真正落地
不复杂但容易忽略











