$bytes_sent 是完整响应总流量,含响应头和响应体,真实反映网络带宽消耗;$body_bytes_sent 仅计响应体,适用于分析业务数据体积,但不可用于带宽限流。

$bytes_sent 是完整响应总流量
它代表 Nginx 实际发给客户端的全部字节数,包含响应头(如 Status、Content-Type、Content-Length 等)和响应体(即真正的数据内容)。这个值直接反映网络层真实发出的字节量,是衡量带宽消耗、计费或限流时最贴近物理事实的指标。
$body_bytes_sent 仅统计响应体大小
它是从 $bytes_sent 中减去响应头长度(r->header_size)后得到的数值,只反映业务数据本身,不包括任何协议开销。比如返回一个 200 OK 响应,响应头占 286 字节,JSON 内容为 1532 字节,则 $bytes_sent = 1818,而 $body_bytes_sent = 1532。
- 适用于评估实际业务负载(如 API 返回的数据体积)
- 不能用于计算网络带宽占用,会系统性低估约 5%–15%(取决于头大小和压缩情况)
- 在启用 gzip 时,$body_bytes_sent 仍是原始未压缩体大小(Nginx 变量层面不感知压缩后体积)
生产中误用的典型场景
很多团队曾用 $body_bytes_sent 做请求级限流,以为“限制响应体大小=控制资源消耗”,但忽略了:大响应头(如含长 Cookie、自定义认证头、大量 Set-Cookie)可能让 $body_bytes_sent 很小,而 $bytes_sent 已超阈值,导致带宽打满或连接阻塞;反之,空响应体但带巨量头(如调试头、追踪头),也会绕过基于 $body_bytes_sent 的策略。
- ❌ 用 $body_bytes_sent 控制单请求带宽配额 → 应改用 $bytes_sent
- ❌ 用 $content_length 或 $request_length 推算响应大小 → 它们属于请求侧变量,与响应无关
- ✅ 用 $body_bytes_sent 分析接口平均 payload 大小、优化 JSON 结构或检测异常空响应
- ✅ 用 $bytes_sent 配合监控看板做出口带宽趋势、识别大响应毛刺、设置连接级速率限制
选型建议:按目标决定用哪个
没有“更好”的变量,只有更匹配场景的变量。关键看你要回答的问题:
- “这条请求占用了多少下行带宽?” → 选 $bytes_sent
- “这个接口平均返回多少有效数据?” → 选 $body_bytes_sent
- “是否该拒绝一个超大响应?” → 用 $bytes_sent 做 limit_rate_after / limit_conn 配合判断
- “是否响应体为空但状态码异常?” → 对比 $body_bytes_sent == 0 且 $status != 204/304
日志中建议同时记录两者,长期观察差值波动可辅助诊断 header 膨胀、中间件注入等问题。不复杂但容易忽略。

















