$upstream_connect_time仅记录TCP建连耗时,不包含TLS握手;真正的TLS握手时延需用$upstream_header_time减去$upstream_connect_time推算,该差值反映TLS握手+请求发送+后端首字节生成总耗时,静态资源场景下可近似为纯TLS开销。

要判断 HTTPS 回源时的 TLS 握手时延,不能直接用 $upstream_connect_time 单独代表“握手耗时”,因为它只记录 TCP 连接建立完成(SYN → ACK)的时间,不包含 TLS 握手阶段。真正的握手时延需通过它与 $upstream_header_time 的差值来间接推算。
明确两个变量的实际覆盖范围
$upstream_connect_time:从 Nginx 发起 connect() 系统调用开始,到 TCP 三次握手完成(收到 SYN-ACK 并发出 ACK)为止。单位秒,精度毫秒,仅反映网络层建连,不含任何 TLS 行为。
$upstream_header_time:从连接建立完成(即 $upstream_connect_time 结束)开始,到 Nginx 收到后端返回的完整响应头(HTTP status line + headers)为止。该过程包含 TLS 握手、请求发送、后端处理、响应头生成与传输。
因此,TLS 握手 + 请求发送 + 后端首字节生成 ≈ $upstream_header_time − $upstream_connect_time。若后端处理极快(如静态资源或缓存命中),该差值就主要体现 TLS 开销。
识别 TLS 握手异常的典型日志模式
-
差值持续在 100–400ms 区间:常见于未启用 TLS session reuse 或证书链较长(含中间 CA)场景;可检查 Nginx 是否配置了
ssl_session_cache shared:SSL:10m和ssl_session_timeout -
差值偶发 > 1s,且
$upstream_connect_time正常(如 0.012):大概率是 TLS 协商失败重试(如 client_hello 不匹配、SNI 错误、服务端不支持客户端 cipher suite),需查error.log中SSL_do_handshake() failed或no suitable protocol类错误 -
差值接近 0(如 0.001–0.003),但
$upstream_header_time显著偏高:说明 TLS 已复用成功,瓶颈转向后端业务逻辑或响应头生成慢(如动态模板渲染、同步 DB 查询)
配置建议:让日志能支撑握手分析
在 http{} 块中定义含关键时间字段的日志格式:
log_format tls_handshake '$remote_addr [$time_local] "$request" ' '$status $upstream_cache_status ' '$upstream_connect_time $upstream_header_time $upstream_response_time ' '"$upstream_addr"';
确保在启用 proxy_pass 且走 HTTPS 回源的 location 中启用该格式,并确认 Nginx ≥ 1.9.1、启用了 http_ssl_module。
辅助验证手段
- 用
openssl s_client -connect origin.example.com:443 -servername origin.example.com -tls1_2手动测试 TLS 握手耗时,与线上日志差值比对 - 开启 Nginx 的
ssl_preread on(配合 stream 模块)可分离 TLS 握手日志,但不适用于 http 层回源分析 - 若使用 OpenResty,可在
ssl_certificate_by_lua_block中埋点计时,精确捕获 handshake 阶段,但需额外开发











