用户在 SSL证书部署后 CPU 飙升,是一个很典型的性能问题。这通常是因为 TLS 握手过程中的非对称加密(RSA/ECC) 和 数据加密传输时的对称加密,消耗了大量的 CPU 计算资源。
要解决这个问题,需要从硬件加速、会话复用、算法优化、软件调优这四个维度入手:
1. 硬件加速(效果最显著)
如果 CPU 飙升是因为非对称加密(特别是 RSA 解密),那么硬件加速是最直接的解决方案。
专用硬件卸载:在高性能硬件或云服务器上,可以开启 QAT,将 RSA 加解密、密钥交换等操作从 CPU 卸载到专用硬件。Nginx 官方有支持 QAT 的版本,云服务器通常也提供了对应的卸载能力(如阿里云、腾讯云的弹性网卡)。
云原生 LB 前置:如果使用云服务,最简单的方式是将证书部署在 SLB/ALB 上,由负载均衡器负责 TLS 卸载。这样后端服务器处理的是 HTTP 明文流量,CPU 负载会大幅下降。
2. 开启会话复用(减少握手次数)
TLS 完全握手涉及最耗 CPU 的非对称运算,如果能让客户端复用之前的会话,CPU 开销会小得多。
Session ID:服务端内存中缓存会话 ID,适用于同一客户端的短时间重连。
Session Ticket:更推荐的方式。服务端将会话信息加密后发给客户端保存,无需服务端存储,无状态、易扩展。在 Nginx 中可通过配置 `ssl_session_tickets on;` 和定期轮换 `ssl_session_ticket_key` 实现。
3. 优化加密算法与协议版本
不同的加密算法,CPU 消耗差异很大。
升级 TLS 1.3:相比 TLS 1.2,TLS 1.3 将握手从 2-RTT 减少到 1-RTT,且大幅精简了加密套件,握手计算量更小、速度更快。
选择 ECC 而非 RSA 证书:如果 CPU 是瓶颈,可以考虑使用 ECC 证书(如 ECDSA)。ECC 在相同安全强度下,密钥更短、计算速度比 RSA 快数倍甚至一个数量级。不过需注意老旧客户端的兼容性。
禁用弱加密套件:避免使用 `CBC` 模式的套件,优先选择 `CHACHA20_POLY1305`(在移动设备上效率高)或 `AES-GCM`(支持 AES-NI 指令集时效率高)。
4. 软件层与系统层调优
启用 AES-NI 指令集:现代 CPU 都支持 AES-NI 指令集,能极大加速对称加密。如果发现 AES 加解密耗 CPU,可以检查一下系统是否加载了该模块:
bash
# 检查是否支持
grep aes /proc/cpuinfo
# 如果没有输出,说明未启用或 CPU 不支持,软件层面可以尝试切换到 CHACHA20 算法
Nginx/OpenSSL 版本:确保使用较新版本的 Nginx 和 OpenSSL 1.1.1 或 3.0 以上版本。旧版本缺乏对现代硬件指令集和 TLS 1.3 的优化支持。
优化进程与缓存:
增大 `ssl_session_cache` 大小:`ssl_session_cache shared:SSL:10m;` 约能缓存 4 万会话。
对于高并发场景,适当增加 Nginx 的 `worker_processes` 和 `worker_connections`,并开启 `use epoll;`。
如果使用了 OCSP Stapling,务必开启。它可以由服务端预先缓存证书吊销状态,避免客户端在握手时额外去 CA 站点查询,从而降低连接延迟和服务器解析开销:
nginx
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/full_chain.pem;
5. 诊断与定位
在优化前,建议先明确 CPU 消耗的具体位置,避免盲目调整:
区分进程:用 `top` 或 `htop` 确认是 Nginx 进程高,还是 后端应用(如 Java、PHP-FPM)进程高。
Nginx 高:通常是 TLS 握手或加解密负担过重,重点优化上述 1-4 点。
后端应用高:可能是应用层处理 HTTPS 回源流量效率低,或者应用本身做了额外的加解密。此时可以考虑在 Nginx 层终止 TLS,后端使用 HTTP 或 Unix Socket。
抓包分析:使用 `tcpdump` 抓包,通过 Wireshark 查看是否有大量 Client Hello后出现 TCP Retransmission 或 TLS 重新协商,这可能暗示会话复用没有生效或网络不稳定导致频繁重握手。
可以先从会话复用和算法优化入手,这两个通常改动成本较低,但效果比较明显。如果业务对延迟不敏感,也可以在监控中观察 TLS 握手时间的变化来验证优化效果。