高并发下Nginx worker CPU触顶主因是TLS握手、连接分发与进程调度三环节失衡,需通过top查worker占比、openssl speed验硬件加速、ss查ESTABLISHED连接数、错误日志定位OCSP卡点,并验证reuseport、CPU亲和性、会话复用及ECDHE+TLSv1.3等配置实效性。

高并发压测下 Nginx worker 进程 CPU 占用率触顶,不是“扛不住流量”,而是某类操作在单位时间内集中爆发、反复消耗 CPU 周期。排查要直击执行层,跳过猜测,用可观测数据定位真实热点。
先确认 CPU 热点是否真在 worker 处理链路
别一看到 top 里 nginx 占高就调参数——先排除干扰项:
- 运行 top -c,只关注 nginx: worker process 行的 %CPU;若 master 进程占比异常高,问题出在配置重载或信号处理,和请求处理无关
- 用 ps -eo pid,psr,cmd | grep 'worker' 查看每个 worker 分布在哪颗 CPU 上;若多个 worker 被调度到同一核,说明没配 CPU 亲和性,存在争抢
- 执行 openssl speed rsa2048,单核吞吐低于 800 ops/sec,表明 AES-NI 或 OpenSSL engine 未启用,TLS 加解密正在纯软算
查 TLS 握手是否成为 CPU 主力消耗源
HTTPS 流量中,握手开销远高于加解密本身。高频短连接会让握手反复触发,直接拖垮 CPU:
- 运行 ss -s | grep -i tls,看 ESTABLISHED 连接数;若超 5000 且压测 QPS 持续上升但连接数不稳,大概率是客户端未复用连接(如 keepalive 被禁、HTTP/1.0 请求、或客户端实现缺陷)
- 检查错误日志:grep "ssl_handshake" /var/log/nginx/error.log | tail -20;大量 timeout 不代表 CPU 不够,更可能是 OCSP Stapling 失败或证书链缺失导致握手卡在远程验证环节
- 确认会话复用是否真正生效:ssl_session_cache 必须写在 http { } 块顶层(不能在 server 里),且缓存大小与超时匹配,例如 ssl_session_cache shared:SSL:32m; ssl_session_timeout 4h;
看连接分发与进程调度是否引入额外开销
worker 进程争抢 accept 锁、频繁跨核迁移、上下文切换过多,都会把 CPU 消耗在调度而非业务上:
- 确认是否启用了 reuseport:listen 指令后加 reuseport(如 listen 443 ssl reuseport;),可绕过内核 accept_mutex,消除惊群效应
- 检查 worker_processes 是否与物理 CPU 核数一致;设为 auto 在容器环境可能误判,建议显式设为 4(4 核机器)或 8(8 核)
- 开启 worker_cpu_affinity 绑定,例如 4 核机器配 worker_cpu_affinity 0001 0010 0100 1000;,减少缓存失效和迁移开销
验证关键配置是否实际生效而非“形同虚设”
很多优化配置写了却没起效,因为位置错、语法错或依赖未满足:
- 密码套件必须强制 ECDHE 优先:ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;,并关闭服务端强推:ssl_prefer_server_ciphers off;
- TLSv1.3 必须显式启用:ssl_protocols TLSv1.2 TLSv1.3;;它默认跳过 ServerHello Done 和 ChangeCipherSpec,握手快 30%–50%
- 禁用 session ticket:ssl_session_tickets off;,避免每次新建 session 都多一次 AES 加解密(尤其在无硬件加速时)











