TLS握手成功率≈(s+r)/(s+r+.),需通过$ssl_session_reused三值分类、结构化日志、vector/filebeat采集及Prometheus比率计算实现实时监控。

要实时获取 Nginx 中 TLS 握手成功率,不能依赖单一模块或日志字段,而需结合 $ssl_session_reused 的语义分类、合理日志结构、轻量采集管道与 Prometheus 聚合逻辑——它本质是一个“计数型比率指标”,不是直接暴露的内置值。
理解 $ssl_session_reused 的三类取值含义
该变量在 OpenResty 或 Tengine 中可用(Nginx 官方版不支持),其值为单字符,直接反映本次 TLS 连接的握手类型:
- s:完整握手(full handshake),即协商新会话,消耗最多 CPU 和 RTT
- r:会话复用(session resumption),通过 Session ID 或 Session Ticket 恢复,跳过密钥交换
- .(英文点):未启用 TLS 或握手失败(如协议不匹配、证书错误、ALPN 协商失败等)
因此,握手成功率 ≈ (s + r) / (s + r + .),分母即所有尝试建立 TLS 连接的请求,分子为成功完成握手的请求(无论是否复用)。
配置带 $ssl_session_reused 的结构化日志
在 server 或 http 块中定义专用日志格式,确保字段对齐、无空格干扰解析:
- 添加 log_format,例如:
log_format tls_success '$remote_addr [$time_local] "$request" $status $ssl_protocol "$ssl_cipher" $ssl_session_reused'; - 将该格式用于 access_log:
access_log /var/log/nginx/tls_success.log tls_success; - 确认 SSL 已启用,且不屏蔽该变量(无需额外模块,但需 OpenResty ≥ 1.21.4.2 或 Tengine ≥ 2.3.3)
用轻量采集器实时转为 Prometheus 指标
不推荐轮询日志文件再解析——延迟高、易丢行。更可靠的方式是使用支持动态标签提取的采集器:
- 推荐 vector 或 filebeat + metricbeat pipeline:配置 grok 解析器,按 $ssl_session_reused 值做条件计数,输出为三个带 label 的计数器,如:
nginx_tls_handshake_total{type="s"} 12489
nginx_tls_handshake_total{type="r"} 87231
nginx_tls_handshake_total{type="."} 312 - 在 Prometheus 中定义即时向量表达式:
rate(nginx_tls_handshake_total{type=~"s|r"}[5m]) / rate(nginx_tls_handshake_total[5m])[5m]
该结果即为最近 5 分钟的 TLS 握手成功率(小数形式,如 0.996 表示 99.6%) - 可在 Grafana 中设置告警:当该值连续 3 个周期低于 0.98 时触发,定位证书过期、OCSP 响应超时或客户端 TLS 版本淘汰问题
补充验证:用 stub_status 辅助判断连接层异常
虽然 stub_status 不提供握手级指标,但它能暴露底层连接异常趋势:
- 在 HTTPS server 块中启用:
location /status { stub_status; allow 127.0.0.1; deny all; } - 关注返回中的 Reading 和 Writing 数值:若 Reading 长期 > 10 且伴随大量 . 日志,可能表示 TLS 握手卡在 ClientHello 或证书验证阶段(如后端 CA 无法访问)
- 该信息与 $ssl_session_reused 指标交叉分析,可区分是协议层失败(如 TLSv1.0 被拒)还是系统层失败(如 fd 耗尽、worker 进程卡住)


















