关键在于分离 SSL 握手 CPU 开销,通过软中断占比、会话复用率、握手延迟等指标交叉验证,结合缓存容量水位、失败率及单核利用率建立可告警的容量模型,并联动配置优化与横向扩容。

监控 Nginx SSL 握手的 CPU 损耗并触发扩容预警,关键在于把“握手开销”从整体 CPU 使用率中分离出来,并建立与会话行为强相关的指标链。单纯看 top 中 nginx worker 的 CPU 占用,无法区分是静态文件分发、反向代理还是 TLS 计算导致——必须结合 Nginx 自身行为特征和系统级信号交叉验证。
抓取真实 SSL 握手 CPU 负载信号
SSL 握手(尤其是全握手)是 CPU 密集型操作,其负载会直接反映在以下可采集指标上:
-
软中断(si)占比突增:TLS 握手大量触发内核 softirq(特别是
NET_RX和RCU),用vmstat 1观察si列持续 >30%,且与 HTTPS 新连接数正相关,说明握手正在吃掉 CPU 时间片 -
worker 进程的 %CPU 与 $ssl_session_reused 强负相关:通过
nginx-module-vts或nginx-prometheus-exporter暴露nginx_http_ssl_handshakes_total和nginx_http_ssl_session_reuses_total;当复用率 -
握手延迟 P95 > 150ms:用
tcpdump + tshark或 OpenResty 的lua-resty-core在ssl_certificate_by_lua*阶段打点,统计从 ClientHello 到 ServerHello 的耗时;该延迟跳涨是 CPU 瓶颈最直接证据
建立可告警的性能容量水位线
不要等 CPU 扛不住才扩容。应基于当前配置预估理论吞吐上限,并提前预警:
-
计算 session cache 实际承载能力:运行
nginx -T | grep ssl_session_cache获取配置大小(如shared:SSL:10m),再用公式理论最大新会话/秒 ≈ cache_size(B) ÷ (0.4KB × ssl_session_timeout(sec))。例如 10MB + 300 秒超时 → 约 5000 新会话/秒。若实测nginx_http_ssl_handshakes_total接近该值的 80%,即触发“缓存饱和预警” -
监控握手失败率:错误日志中
SSL_do_handshake() failed或no suitable key share等报错,配合rate(nginx_http_ssl_handshakes_failed_total[5m]) > 0.5,说明 TLS 层已不堪重负,需立即干预 -
绑定 CPU 核心后的单核利用率:若已配置
worker_cpu_affinity,用pidstat -t -p $(pgrep nginx) 1查看各 worker 线程在对应核心上的 %CPU;单核持续 >90% 即为硬瓶颈,不可仅靠加 worker 数解决
自动扩容预警与快速响应路径
预警不是目的,要能驱动动作。建议组合以下策略形成闭环:
-
Prometheus 告警规则示例:
groups:
- name: nginx-ssl-capacity
rules:
- alert: SSLSessionCacheSaturation
expr: (nginx_http_ssl_handshakes_total{job="nginx"} - nginx_http_ssl_session_reuses_total{job="nginx"}) / nginx_http_ssl_handshakes_total{job="nginx"} > 0.2 and nginx_http_ssl_handshakes_total{job="nginx"} > 1000
for: 3m
labels:
severity: warning
annotations:
summary: "SSL session cache hit rate low, full handshakes surging" -
扩容前必做的三件事:检查
ssl_session_tickets on是否启用(无状态补充)、确认ssl_protocols TLSv1.2 TLSv1.3已禁用旧协议、验证ssl_ciphers是否含ECDHE-ECDSA-AES128-GCM-SHA256等高效套件——这些优化常比加机器更有效 -
横向扩容阈值参考:当单机
ssl_handshakes_total/sec> 3000 且avg by(instance)(100 * (rate(process_cpu_seconds_total{job="nginx"}[5m]))) > 75,即可启动 LB 后端新增节点;注意同步更新所有节点的ssl_session_cache shared:SSL:xxm大小,避免新节点过早溢出











