nginx stream模块无法使用$upstream_response_time,应依赖$upstream_connect_time和$session_time等连接级变量实现tcp代理响应时间监控,并通过定制日志、nginx-stream-exporter及抓包工具完成可观测性建设。

Nginx 的 TCP 代理(stream 模块)本身不提供 $upstream_response_time 这类 HTTP 层变量,但依然可以实现后端响应时间监控——关键在于用对变量、配好日志、选准工具链。它不依赖应用层协议,而是基于连接级时序采集,适合数据库、Redis、gRPC over TCP 等非 HTTP 服务。
使用 $upstream_response_time 在 stream 块中是无效的
该变量仅在 http 模块的 proxy_pass 场景下可用。TCP 代理走的是 stream 上下文,没有“响应头”概念,因此 $upstream_response_time、$upstream_header_time 等均为空或不生效。
正确方式:用 $upstream_connect_time + $upstream_response_time(需 patch 或 OpenResty)
标准 Nginx stream 模块从 1.9.0 起支持以下两个核心变量(需 ≥1.9.0):
-
$upstream_connect_time:TCP 连接建立耗时(单位:秒,毫秒精度),记录从发起 connect 到完成三次握手的时间; -
$upstream_response_time:仅在启用proxy_responses并配置proxy_timeout后,且后端有明确响应包时才可能有值 —— 但这不是标准行为,多数情况下为-。
更可靠的做法是:
- 记录
$upstream_connect_time,作为建连阶段延迟基线; - 结合
log_format中的$time_iso8601和$msec,配合客户端或后端打点,做端到端 RTT 对齐; - 若需真实“响应耗时”,必须由后端主动返回带时间戳的响应,或通过
tcpdump/tcprstat等系统工具补全。
配置 stream 日志采集响应相关指标
在 stream 块中定义日志格式(注意:log_format 需在 stream { } 内声明):
stream {
log_format stream_metrics
'$remote_addr:$remote_port - [$time_iso8601] '
'$protocol $status $bytes_sent $bytes_received '
'$upstream_addr $upstream_connect_time $upstream_response_time '
'$session_time';
access_log /var/log/nginx/stream_metrics.log stream_metrics;
upstream db_cluster {
server 10.0.1.20:5432;
server 10.0.1.21:5432;
}
server {
listen 5433;
proxy_pass db_cluster;
proxy_timeout 30s;
proxy_responses 1; # 允许等待 1 个响应包(用于简单协议)
log_format stream_metrics ...; # 启用上面定义的格式
}
}
说明:
-
$session_time是 stream 模块原生变量,表示整个连接存活时长(单位:秒),可近似反映“会话级响应延迟”; -
$upstream_connect_time可靠,用于识别后端节点建连慢问题(如防火墙拦截、端口未开、SYN 重传); -
$upstream_response_time在多数 TCP 协议中不可用,除非协议有明确 request-response 模式且 Nginx 能识别响应边界(如 MySQL 协议需mysql模块支持)。
接入可观测系统:Prometheus + nginx-stream-exporter
官方 nginx-prometheus-exporter 默认只支持 http 指标。要监控 stream 流量,推荐:
- 使用 nginx-stream-exporter(第三方开源项目),它解析
streamaccess log,提取$upstream_connect_time、$session_time等字段,暴露为 Prometheus 指标; - Grafana 中用
histogram_quantile(0.90, sum(rate(nginx_stream_upstream_connect_seconds_bucket[5m])) by (le))计算 P90 建连耗时; - 对
$session_time做直方图聚合,识别长连接异常(如空闲超时、意外断连)。
补充:轻量级验证与调试技巧
- 用
nc -zv host port快速测建连延迟,对比$upstream_connect_time是否一致; - 抓包验证:
tcpdump -i any port 5432 -w db.pcap,用 Wireshark 查看 SYN/SYN-ACK 时间差; - 若后端支持,可在响应包开头写入纳秒级时间戳,Nginx 用 Lua 模块(OpenResty)读取并记录差值。
不复杂但容易忽略。











