nginx中$ssl_*变量非零成本,滥用会显著降低性能;应仅按需保留$ssl_protocol、$ssl_cipher等低开销字段,禁用$ssl_client_cert等高开销变量,并在https专用server/location内定义日志格式。

直接看日志格式和 SSL 变量使用情况——这是 Nginx HTTPS 性能退化的最常见、最容易被忽略的根源。
重点查日志配置里的 $ssl_* 变量
Nginx 中的 $ssl_protocol、$ssl_cipher 等变量不是“免费”的。每次写入 access_log 都要从 OpenSSL 上下文中实时提取,高频请求下会明显抬高 CPU 缓存压力。
- 只在确有需要时保留 1–2 个低开销字段,比如 $ssl_protocol(看 TLS 版本分布)、$ssl_cipher(排查协商问题)
- 彻底禁用 $ssl_client_cert、$ssl_client_raw_cert、$ssl_client_s_dn 等高开销变量——它们会触发证书解析、ASN.1 解码甚至 KB 级内存拷贝
- 切勿把任何 $ssl_* 变量写在全局 log_format 里,否则 HTTP 请求也会白跑一遍 SSL 上下文检查
确认 SSL 日志格式的作用域是否隔离
HTTPS 日志应严格限定在启用 SSL 的 server 或 location 块内,避免污染非 HTTPS 流量。
- 删除 nginx.conf 顶层的 log_format 中所有 ssl_* 字段
- 改用嵌套定义:在 listen 443 ssl 的 server 块里单独声明 log_format https_log ...,再通过 access_log 指向它
- 如需条件记录(例如只在客户端证书验证成功时记 DN),用 map 指令做映射,而不是无差别展开
验证真实性能影响,别靠猜测
加了几个 SSL 日志字段,到底慢了多少?必须量化。
- 用 wrk 或 ab 对同一接口压测:一次关闭 SSL 日志变量,一次开启,对比 QPS 和 P95 延迟
- 观察 worker 进程 CPU 使用率变化,特别是 sys 时间占比是否上升
- 检查 error.log 是否出现 “*worker process is shutting down” 或频繁重载提示——这往往是日志拷贝卡住进程的信号
顺带检查基础 SSL 配置合理性
性能退化有时也来自低效的 TLS 处理本身。
- 确认启用了 ssl_buffer_size 并设为 4k,减少分片与上下文切换次数
- 避免过度收紧 ssl_ciphers,过于复杂的套件协商会增加握手耗时
- 确保 ssl_protocols 至少包含 TLSv1.2,禁用已淘汰的 SSLv3/TLSv1.0(既不安全又更慢)











