$upstream_http_connection 是 Nginx 捕获后端实际返回的 Connection 响应头值,用于客观验证其是否真正维持长连接;需结合 TCP 连接稳定性与后端 keepalive timeout 交叉验证,避免因中间件覆盖、响应头重写或超时不一致导致误判。

$upstream_http_connection 是 Nginx 提供的一个变量,用于捕获后端服务在响应中实际返回的 Connection 响应头值。它本身不“表达意图”,但能帮你**客观验证后端是否真正维持长连接行为**——这是判断其长连接支持真实性的最直接依据。
为什么不能只看文档或配置?
很多框架(如 Spring Boot、Express、Gin)默认开启 HTTP/1.1,理论上应返回 Connection: keep-alive,但实践中常被显式覆盖:
- 中间件或安全插件主动注入
Connection: close - 反向代理(如另一层 Nginx、Traefik)重写了响应头
- 应用代码中手动设置了
res.setHeader('Connection', 'close')(Node.js)或等效逻辑 - JVM 参数或容器网关限制了 keepalive timeout,导致后端提前发 FIN
如何用 $upstream_http_connection 获取真实信号?
在 location 块中添加日志记录或条件判断:
示例:记录每次响应的 Connection 头
log_format upstream_conn '$remote_addr - $upstream_http_connection "$request" $status';
重启后查看 access log,典型输出可能为:
-
10.0.1.5 - keep-alive "GET /api/user HTTP/1.1" 200→ 后端明确支持 -
10.0.1.5 - close "GET /api/user HTTP/1.1" 200→ 后端拒绝复用 -
10.0.1.5 - "" "GET /api/user HTTP/1.1" 200→ 后端未返回该头(HTTP/1.1 下默认语义是 keep-alive,但需结合其他指标确认)
必须配合验证的两个关键行为
单看 $upstream_http_connection 不够,需交叉验证:
-
TCP 连接稳定性:用
netstat -ant | grep :8080 | grep ESTABLISHED | wc -l观察一段时间内到后端的 ESTABLISHED 连接数是否趋于平稳(如维持在 20–40),而非频繁波动(如 1→150→3→120)。剧烈波动说明连接被快速关闭,即使头写的是 keep-alive 也无效 -
后端 Keep-Alive 超时设置:检查后端服务的 keepalive timeout(如 Tomcat 的
connectionTimeout、Spring Boot 的server.tomcat.connection-timeout)。若设为 5 秒,而 Nginx 的keepalive_timeout是 60 秒,那么连接大概率在复用前就被后端单方面断开
常见误判场景
以下情况容易让人误以为后端支持长连接:
- Nginx 配置了
proxy_http_version 1.1和proxy_set_header Connection "",但后端响应中仍出现Connection: close→ 实际是后端强制关闭 - 日志里看到
$upstream_http_connection为空,就认为“没问题” → 空值在 HTTP/1.1 下虽合法,但若后端 TCP 层立即发 FIN,仍是短连接 - 抓包看到多个请求走同一个 TCP 流(Follow TCP Stream 显示多条 request/response)→ 表面像长连接,但若每个 response 后都有 RST 或 FIN,则只是“伪复用”











