高价值带宽消耗仅统计状态码为200/206/304、非低价值路径(如favicon.ico)、且响应体≥10KB的成功响应;需结合Nginx日志变量与map规则精准提取并过滤,避免误计错误响应、小资源及CDN压缩干扰。

直接用 $body_bytes_sent 加状态码统计高价值带宽消耗,关键不在“怎么加”,而在“怎么定义高价值”——它不是所有 200 响应都算,也不是所有大响应体都该被标记。核心逻辑是:**只统计成功返回且业务意义明确的大体积响应**,排除错误响应、小资源、重定向和空响应的干扰。
明确“高价值”的三个筛选条件
单纯看 $body_bytes_sent 数值会误把 404 页面、调试日志输出、甚至攻击扫描响应也计入。必须叠加以下三重判断:
-
状态码限定为 200、206、304:200 是主内容交付;206(范围请求)常见于音视频分片,单次虽小但频次高、总带宽大;304 虽不传 body,但
$body_bytes_sent为 0,需单独归为“缓存有效型低带宽路径”,用于反向识别哪些路径本可更早缓存 -
排除已知低价值路径:如
/favicon.ico、/robots.txt、健康检查端点(如/healthz)、前端 sourcemap(.map文件)等,即使返回 200 且体积不小,也不计入高价值 - 设定最小有效体积阈值:例如 ≥ 10 KB。低于该值的 HTML、JSON 接口响应通常属控制类流量,不算带宽消耗主力;而 ≥ 10 KB 很可能对应图片、PDF、API 批量数据、渲染后 HTML 等真实用户获取的内容
Nginx 日志格式中精准提取路径与带宽
在 log_format 中组合变量,确保每条日志含路径、状态码、响应体字节数,并过滤掉无效记录:
log_format highvalue '$time_iso8601\t$request_method\t$uri\t$status\t$body_bytes_sent'; access_log /var/log/nginx/highvalue.log highvalue if=$highvalue_flag;
其中 $highvalue_flag 是自定义变量,定义如下:
map $status $highvalue_flag {
default 0;
200 1;
206 1;
304 1;
}
map $uri $is_lowvalue_uri {
~*\.(ico|txt|map|svgz?)$ 1;
~*/healthz$ 1;
~*/ping$ 1;
default 0;
}
map $body_bytes_sent $is_large_body {
~^[1-9][0-9]{4,}$ 1; # ≥ 10000 字节
default 0;
}
set $highvalue_flag 0;
if ($highvalue_flag) {
set $highvalue_flag 1;
}
if ($is_lowvalue_uri) {
set $highvalue_flag 0;
}
if ($is_large_body = 0) {
set $highvalue_flag 0;
}注意:Nginx 的 if 在 location 外不可嵌套,实际部署建议用更稳定的 map 链式判断或改用 OpenResty 的 Lua 做精细控制。
按路径聚合分析,识别真实高消耗源头
日志生成后,用简单命令快速定位问题路径:
# 按路径汇总总带宽(字节),取 Top 20
awk '$4 == "200" || $4 == "206" {sum[$3] += $5} END {for (p in sum) print sum[p], p}' highvalue.log | sort -nr | head -20
<h1>查看某路径的平均响应大小和调用量</h1><p>awk '$3 ~ /^\/api\/report/ && $4 == "200" {total += $5; count++} END {print "avg:", total/count, "count:", count}' highvalue.log重点观察两类路径:
-
高频+中等体积路径:如
/api/user/profile(平均 80 KB,日均 50 万次)→ 总带宽 ≈ 40 GB/天,优化 JSON 字段裁剪或启用 gzip 可立竿见影 -
低频+超大体积路径:如
/export/invoice?month=2024-06(平均 12 MB,日均 200 次)→ 单次成本高,应推动客户端分页导出或服务端流式压缩
避免常见误判陷阱
几个高频踩坑点必须提前规避:
-
gzip 开启时
$body_bytes_sent是压缩后大小,它反映的是真实网络传输量,正是你要统计的“带宽消耗”,无需还原原始大小 -
POST/PUT 请求的
$body_bytes_sent通常是 0 或极小值,因响应体不承载主体内容,别把它和上传流量混淆;上传带宽应监控$request_length或客户端上报 -
CDN 回源日志中,
$body_bytes_sent是 CDN 收到的响应大小,若 CDN 启用了压缩或图片 WebP 转换,该值已非源站原始体积,需确认 CDN 是否透传原始 header 或提供独立带宽报表

















