nginx 默认不记录 tcp 连接复用次数,但可通过 $connection_requests 变量在 access.log 中间接标记:该变量表示当前连接已处理的请求数(含本次),长连接中递增,短连接恒为 1。

默认情况下,Nginx 的 access.log 不会记录单个 TCP 连接上复用了多少次 HTTP 请求(即长连接复用次数)。这是因为 access 日志按请求(request)记录,而非按连接(connection)记录。但你可以通过组合使用内置变量和日志格式,**间接估算或标记长连接的复用行为**,最常用且实用的方式是利用 $connection_requests 变量。
核心方法:用 $connection_requests 记录当前连接已处理的请求数
$connection_requests 是 Nginx 内置变量,表示**当前 TCP 连接上已处理的 HTTP 请求数(含本次)**。它在每个请求日志中实时更新,是识别长连接复用最直接的依据。
- 首次建立连接时,该值为 1
- 若连接未断开、后续请求复用该连接,则第二次请求时值为 2,第三次为 3,依此类推
- 该变量只在 keepalive 连接中递增,短连接(
Connection: close)每次都是 1
配置示例:在 log_format 中加入 connection_requests
修改 Nginx 配置(如 http 块内),定义带复用计数的日志格式:
log_format with_conn_req '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'conn=$connection conn_req=$connection_requests '
'rt=$request_time uct=$upstream_connect_time uht=$upstream_header_time urt=$upstream_response_time';
access_log /var/log/nginx/access.log with_conn_req;
重启 Nginx 后,日志中会出现类似:
192.168.1.100 - - [10/Jul/2024:14:22:35 +0800] "GET /api/v1/users HTTP/1.1" 200 1245 "-" "curl/7.68.0" conn=12345 conn_req=1 rt=0.023 ... 192.168.1.100 - - [10/Jul/2024:14:22:35 +0800] "GET /api/v1/orders HTTP/1.1" 200 892 "-" "curl/7.68.0" conn=12345 conn_req=2 rt=0.018 ... 192.168.1.100 - - [10/Jul/2024:14:22:36 +0800] "GET /api/v1/profile HTTP/1.1" 200 431 "-" "curl/7.68.0" conn=12345 conn_req=3 rt=0.011 ...
同一 conn 值(连接 ID)下,conn_req 递增,即表明发生了长连接复用。
进阶分析:统计平均复用次数与连接效率
仅记录不够,还需分析。可通过日志聚合快速计算关键指标:
-
单连接平均请求数:对每组相同
conn的日志取max(conn_req),再对所有连接求平均 -
复用率:满足
conn_req > 1的请求占比,反映长连接实际利用率 -
高复用连接识别:筛选
conn_req > 10的请求,检查是否异常(如客户端未正确关闭、连接泄漏)
例如用 awk 快速统计平均复用次数:
awk '{req[$9] = $12} END {for (c in req) sum += req[c]; print "avg =", sum/NR}' \
RS=' ' FS='[ \"]' /var/log/nginx/access.log | \
grep 'conn_req=' | awk '{sum+=$NF; n++} END{print "Avg conn_req:", sum/n}'
注意事项与常见误区
$connection_requests 虽好,但需注意边界条件:
- 该变量在 worker 进程内有效,跨 worker 不共享;若启用了多 worker 且无连接亲和(如负载均衡器未做 session stickiness),同一客户端可能被分到不同 worker,
connID 会重复,但不影响conn_req在本 worker 内的单调性 - 不适用于 HTTP/2 —— HTTP/2 天然多路复用,
$connection_requests表示该 TCP 连接上的流(stream)总数,语义略有不同,但仍可反映复用强度 - 无法区分“主动 keepalive” 和 “被动等待超时断开”,需结合
$request_time和keepalive_timeout配置综合判断
不复杂但容易忽略。











