本质是TLS握手密集爆发引发的计算型瓶颈,需通过禁用RSA、启用ECDHE密码套件、扩大会话缓存、OCSP装订及压测端JVM调优等协同措施降低CPU负载。

高并发压测下 HTTPS 建立连接导致系统 CPU 瞬时打满,本质是 TLS 握手密集爆发引发的计算型瓶颈,不是配置漏写或参数调错就能立刻缓解的表层问题。核心在于:每秒数百甚至上千次完整握手(尤其是 RSA 密钥交换)会持续抢占 CPU,尤其在短连接、低复用率场景中尤为剧烈。
确认是否真是 TLS 握手压垮 CPU
别急着调参数,先锁定根因:
- 运行 top -c,看高 CPU 进程是否为 nginx: worker process 或压测客户端(如 JMeter 的 JVM 进程)
- 执行 openssl speed rsa2048,单核吞吐若低于 800 ops/sec,说明硬件不支持加速或未启用
- 查当前 TLS 连接数:ss -s | grep -i tls,若 ESTABLISHED 超过 3k 且持续攀升,大概率是握手风暴
- 检查 Nginx 错误日志:grep "ssl_handshake" /var/log/nginx/error.log | tail -15,大量 timeout 不是网络问题,而是握手卡在计算环节
强制启用高效密码套件与硬件加速
让每次握手尽可能轻量、快速,避免 CPU 硬算:
- 禁用 RSA 密钥交换(最耗 CPU),只保留 ECDHE + ECDSA/CHACHA20/AES-GCM 组合:
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305; - 关闭服务端优先选密:ssl_prefer_server_ciphers off;,把选择权交给客户端,提升协商成功率
- 确认内核已加载加速模块:lsmod | grep -E "(qat|ccp)";再确认 Nginx 编译时含 OpenSSL 引擎支持:nginx -V 2>&1 | grep -o with-openssl
- 若使用 Intel CPU 且已部署 QAT 驱动,需额外在 OpenSSL 配置中启用引擎,并在 Nginx 中通过 ssl_engine qat 显式调用(需自编译支持)
大幅降低握手频次与连接开销
减少“新建连接”本身就是最直接的降 CPU 手段:
- 开启并扩大会话缓存:ssl_session_cache shared:SSL:20m;(20m ≈ 支持约 16 万个会话)
ssl_session_timeout 4h; - 启用 OCSP Stapling,省去客户端向 CA 发起验证请求的往返:
ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /path/to/fullchain.pem; - 对压测客户端(如 JMeter)调整 JVM 参数,防止 SSL session cache 耗尽内存引发频繁 GC:
-Djavax.net.ssl.sessionCacheSize=2048 -Djavax.net.ssl.sessionTimeout=300 - 服务端启用 HTTP/2 并延长 keepalive:
http2_max_requests 1000; keepalive_timeout 30s; keepalive_requests 1000;
压测端协同优化(常被忽略的关键一环)
JMeter 本身在 HTTPS 压测中极易成为瓶颈源:
- 默认每个线程维护独立 SSL session cache(软引用,大小 20480),500 线程即占用上亿对象,触发高频 YoungGC,CPU 全耗在 GC 上
- 改用 HTTP Request Defaults → SSL Manager 复用 session,或直接在启动脚本中加 JVM 参数限制缓存大小
- 避免使用 GUI 模式压测,改用命令行非 GUI 模式:jmeter -n -t test.jmx -l result.jtl
- 压测机本身也建议启用 TCP Fast Open 和调优:echo 3 > /proc/sys/net/ipv4/tcp_fastopen











