$upstream_bytes_received精准统计Nginx从上游服务器接收的完整响应字节数(含响应头),适用于评估后端数据输出压力;需通过自定义日志格式、backend映射分离、shell累加及时间维度分析实现按节点精确计量与趋势洞察。

直接用 $upstream_bytes_received 统计后端下行总流量,关键在于它代表 Nginx 从每个上游服务器实际接收到的**完整响应数据量(含响应头)**,不是客户端看到的流量,而是你代理层“收进来”的真实字节数。这比 $body_bytes_sent 更适合评估后端吐出的数据压力。
一、确认日志格式中已启用 $upstream_bytes_received
在 http 块中定义一个带该变量的日志格式,例如:
log_format upstream_full '$remote_addr - $remote_user [$time_local] ' '"$request" $status $upstream_status ' '$upstream_addr $upstream_response_time $upstream_bytes_received ' '"$http_user_agent"';
注意:$upstream_bytes_received 是 Nginx 接收自 upstream 的总字节数,包含响应头和响应体;它与 $upstream_response_length(仅 body)不同,也不同于 $body_bytes_sent(发给客户端的 body 字节数)。
确保在对应 location 或 server 块中启用了该日志:
- access_log /var/log/nginx/upstream-received.log upstream_full;
- 务必保证该日志路径所在目录存在,且 Nginx 进程有写权限
- 若使用了多级 upstream(如 fallback 或 proxy_next_upstream),
$upstream_bytes_received只记录**最终成功响应的那个后端**的数据
二、按后端节点分离并统计总接收量
单靠全局日志无法区分各节点贡献,需先将日志按实际转发地址拆开:
在 http 块中添加映射:
map $upstream_addr $backend_id { default "unknown"; "192.168.5.10:8080" "node-a"; "192.168.5.11:8080" "node-b"; "192.168.5.12:8080" "node-c";}
再定义含 $backend_id 和 $upstream_bytes_received 的格式,并动态写入不同文件:
log_format node_rx '$backend_id $upstream_bytes_received $time_local'; access_log /var/log/nginx/backend/$backend_id-rx.log node_rx;
这样每台后端的接收字节都会独立落盘,避免交叉干扰。
- 日志文件名含
$backend_id,需提前创建/var/log/nginx/backend/目录 - 配合
logrotate防止单文件过大(尤其高吞吐场景) - 若
$upstream_addr含多个地址(如重试后切换),该变量只取最后一个,符合“最终接收”语义
三、用 shell 快速汇总各节点总接收量
对每个节点日志文件执行累加即可获得精确总字节数:
查看 node-a 总接收量(单位:字节):
awk '{sum += $2} END {print sum+0}' /var/log/nginx/backend/node-a-rx.log
批量统计所有节点(假设日志都在同一目录):
for f in /var/log/nginx/backend/*-rx.log; do b=$(basename "$f" -rx.log); t=$(awk '{sum += $2} END {print sum+0}' "$f"); echo "$b: $t B"; done | sort
如需换算为 MB/GB,可在 awk 中除以 1024² 或 1024³:
awk '{sum += $2} END {printf "%.2f MB\n", sum/1024/1024}' node-a-rx.log
四、结合时间维度分析接收趋势
单纯总量不够,要看出入向压力是否平稳或是否存在异常突增:
按小时统计 node-a 每小时接收字节数:
awk '$1=="node-a" {hr=substr($3,2,13); bytes[hr] += $2} END {for (h in bytes) print h, bytes[h] "B"}' /var/log/nginx/backend/node-a-rx.log | sort
输出形如:18/June/2026:14 12847321B,可导入 Excel 或 Grafana 做折线图。
- 对比同一时段内
$upstream_response_time,若字节数飙升但延迟未升,说明是大响应体导致(如文件下载、导出报表) - 若字节数稳定但
$upstream_status中 5xx 突增,则可能是后端返回错误页(HTML 错误页体积大) - 注意:空响应(204/304)时
$upstream_bytes_received仍可能 > 0(因含响应头),需结合状态码交叉判断


















