最直接有效的方式是利用nginx的$ssl_handshake_time变量实现https握手耗时监控,需nginx 1.19.4+或openresty≥1.21.4.2,配合定制日志格式、prometheus采集及shell快速分析。

最直接有效的方式是利用 Nginx 自带的 $ssl_handshake_time 变量,配合标准 access_log 和日志分析工具,无需改代码、不依赖额外组件,5 分钟内即可上线监控。
确认环境支持并启用变量
Nginx 1.19.4+ 或 OpenResty ≥ 1.21.4.2 才原生支持该变量。它仅在 HTTPS 握手成功后赋值(单位:秒,微秒精度),失败、超时或会话复用时为空。
- 运行
nginx -v验证版本;若为 OpenResty,需检查是否 ≥ 1.21.4.2 - 在 server 块中临时添加测试日志:
log_format test_ssl '$remote_addr - $ssl_handshake_time $ssl_protocol';<br>access_log /var/log/nginx/ssl_test.log test_ssl;
- 重启 Nginx,用浏览器或 curl 访问一次 HTTPS 页面,检查日志是否出现类似
203.0.113.5 - 0.031428 TLSv1.3的记录
定制日志格式以支撑多维分析
把握手耗时和关键上下文绑定,才能定位问题根源。推荐以下 log_format:
log_format ssl_full '$time_iso8601 $remote_addr $host $ssl_protocol $ssl_ciphers $ssl_handshake_time $request_time $upstream_response_time';- 其中
$host区分多域名,$ssl_protocol和$ssl_ciphers可用于比对 TLS 版本与密钥交换性能差异 - 将该格式应用到所有 HTTPS server 块的 access_log 指令中
用 Prometheus + Exporter 实现实时指标采集
若已有 Prometheus 生态,可借助 nginx-prometheus-exporter 或 OpenResty 的 Lua 方案暴露指标:
- 使用 nginx-prometheus-exporter 时,确保其能读取 access_log 并解析
$ssl_handshake_time字段(需开启--nginx.scrape-uri或配置 log parser) - 更精准的做法是 OpenResty +
lua-resty-prometheus:在ssl_certificate_by_lua_block中用ngx.now()打点,构建直方图nginx_ssl_handshake_seconds,标签包含server_name、protocol - Prometheus job 抓取时,建议加
metric_relabel_configs过滤出nginx_ssl_handshake_seconds_.*类指标,并设置分位桶(如 0.05–1.0 秒,覆盖公网典型范围)
快速验证与日常巡检命令
不依赖可视化平台,也能用 shell 快速掌握当前状态:
- 查看最近 1 万条中平均/最大握手耗时:
tail -10000 /var/log/nginx/access.log | awk '{sum += $6; if ($6 > max) max = $6} END {print "avg:", sum/NR, "max:", max}' - 找出慢握手(>300ms)且高频访问的客户端 IP:
awk '$6 > 0.3 {print $2}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10 - 按域名统计 P95 耗时(需 GNU awk):
awk '{a[$3] = a[$3] $6 " "} END {for (i in a) {n = split(a[i], b, " "); asort(b); print i, b[int(n*0.95)]}}' /var/log/nginx/access.log











