直接用 Nginx 日志的 $body_bytes_sent 和 $gzip_ratio 即可对比压缩前后流量,$gzip_ratio 非“-”且 $http_accept_encoding 含 gzip 时才有效,排除二进制资源后,按路径取均值反推原始体积并计算节省量,再结合 $request_time 等指标验证真实体验提升。

直接用日志里的 $body_bytes_sent 和 $gzip_ratio 两个变量就能完成压缩前后流量体积的对比,不需要额外工具或人工测文件。关键不是“理论上能压多少”,而是“实际发给用户多少字节”。
配置日志格式,确保采集核心字段
在 Nginx 的 http 块中定义含压缩信息的日志格式:
然后启用该格式:
access_log /var/log/nginx/gzip_access.log gzip_detail;注意:$gzip_ratio 只对真正被压缩的响应返回小数(如 0.65),未压缩时为 -,不能参与数值计算;$body_bytes_sent 是不含响应头的纯 body 传输量,正是你要对比的“用户收到的体积”。
筛选真实压缩请求,排除干扰样本
只统计确实走 Gzip 流程的请求,否则数据会失真:
- 用
awk '$6 != "-"'过滤掉$gzip_ratio为-的行(即未压缩) - 同时加条件
$7 ~ /gzip/确保$http_accept_encoding包含gzip,避免客户端不支持却被误计入 - 排除图片、字体、视频等二进制资源:它们默认不压缩,若
$gzip_ratio非-,说明gzip_types配置有误(比如误加了image/*)
计算压缩前后体积并做分组对比
对每类静态资源(如 /app.js、/style.css),执行三步推算:
- 取该路径下所有有效样本的平均
$body_bytes_sent(记为S_compressed)和平均$gzip_ratio(记为R) - 反推原始体积:
S_original ≈ S_compressed / (1 − R)(仅当R > 0) - 单次节省体积 =
S_original − S_compressed;压缩率 =R × 100%
例如某 JS 文件平均 $body_bytes_sent = 82400 字节,平均 $gzip_ratio = 0.68 → 原始约 265 KB → 每次响应节省约 183 KB。
验证压缩是否真正影响终端体验
体积变小不等于用户感知更快,要结合耗时指标交叉判断:
- 对比开启 Gzip 前后,
$request_time超 1 秒的请求数是否下降(用awk '$6 > 1 {count++} END {print count}') - 检查
$upstream_response_time是否接近$request_time:若前者远小于后者,说明网络或客户端延迟主导,Gzip 效果有限 - HTTPS 场景下,若 TLS 握手慢(需 Nginx ≥ 1.19.2 +
$ssl_handshake_time),可能掩盖压缩收益,应单独排查


















