nginx https性能优化核心是减少完整握手次数、降低单次计算量、均衡负载,需从协议(tlsv1.2/1.3、高效密码套件)、缓存(共享session缓存+ticket)、密码(限定曲线与签名算法)、系统调度(cpu绑定、reuseport)四层面协同调优。

核心是减少完整握手次数、降低单次握手计算量,并让负载分布更合理。不是靠加机器硬扛,而是从协议、缓存、密码、系统调度四个层面协同优化。
启用高效会话复用,避免重复密钥计算
每次完整 TLS 握手都要做椭圆曲线运算或 RSA 解密,CPU 开销大。复用已有会话可跳过这一步,耗时下降 70% 以上。
- 必须在 http 块顶层 配置共享缓存:
ssl_session_cache shared:SSL:10m;(不能写在 server 里,否则各 worker 不共享) - 配合
ssl_session_timeout 20m;—— 默认 5 分钟太短,用户切后台、APP 唤醒常错过复用窗口;设为 20 分钟实测可降延迟 40% 以上 - 开启 session ticket 双保险:
ssl_session_tickets on;+ssl_session_ticket_key /etc/nginx/ssl/ticket.key;,客户端存票据,服务端压力更小 - 验证是否生效:用
openssl s_client -connect example.com:443 -reconnect看输出中是否频繁出现 Reused, SSL handshake succeeded;日志中加$ssl_session_reused统计 r/. 比例,长期低于 60% 就说明配置没起作用或缓存太小
精简 TLS 协商路径,砍掉低效计算
客户端发来一堆冷门曲线和签名算法,Nginx 要逐个匹配校验,白白消耗 CPU。直接限定范围,缩短协商链路。
- 强制优先使用高效曲线:
ssl_conf_command Curves X25519:secp256r1;(剔除 secp384r1/secp521r1 等高开销选项) - 明确签名算法白名单:
ssl_conf_command SignatureAlgorithms ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256:rsa_pkcs1_sha256;,去掉所有 SHA-1 和弱填充组合 - 只启用 TLSv1.2 和 TLSv1.3:
ssl_protocols TLSv1.2 TLSv1.3;;TLSv1.3 握手从 2-RTT 降到 1-RTT,CPU 消耗比 v1.2 低 30%~50% - 密码套件聚焦 ECDHE+AEAD:
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;,禁用 RC4、3DES、CBC 模式
调优系统级资源分配,防止软中断打满 CPU
HTTPS 新连接涌入时,大量软中断(NET_RX、RCU)会集中打到某几个 CPU 核上,造成单核 90%+ 利用率,而其他核空闲——这不是负载不均,是内核收包和 TLS 处理没对齐。
- 绑定 worker 进程到特定 CPU 核:
worker_cpu_affinity auto;或显式指定,再用pidstat -t -p $(pgrep nginx) 1查看各线程在对应核上的 %CPU - 确认
vmstat 1中的 si(softirq)列是否持续 >30%,若与 HTTPS 新连接数正相关,说明软中断已成瓶颈 - 启用
SO_REUSEPORT(Nginx ≥ 1.9.1):listen 443 ssl http2 reuseport;,让内核把连接更均匀分发到不同 worker - 适当调高连接上限:
worker_connections 10240;+events { use epoll; multi_accept on; },减少 accept 阻塞
关闭非必要特性,避免隐性 CPU 消耗
有些功能看似增强安全或体验,实际在高并发下反而拖慢握手、增加等待或触发额外计算。
-
OCSP Stapling 要谨慎开启:必须配
resolver 1.1.1.1 8.8.8.8 valid=300s;和resolver_timeout 3s;,否则握手阶段卡 DNS 查询,导致 worker 阻塞、上下文切换飙升 - 禁用 ssl_buffer_size 过小值:如设为 1KB,会导致 TLS 记录层频繁分片,触发多次加密调用;保持默认或设为 4K–8K 更稳
- keepalive_timeout 不影响证书校验:它只管 HTTP 层连接空闲时间,设为 30s 左右即可,过长会积压空闲连接、挤占 fd 资源
-
不用 builtin 缓存:如
builtin:1000,每个 worker 自己维护一份,复用率几乎为零,纯属浪费











