通过Nginx日志变量$ sent_http_content_encoding等可低成本评估压缩算法真实带宽收益,关键在于按场景(如移动端JSON、Chrome HTML)分析有效节省,需过滤304、区分deflate/gzip、排除图片等无效压缩。

直接通过 Nginx 的 $sent_http_content_encoding 变量配合日志与简单聚合,就能低成本、低侵入地评估不同压缩算法在真实流量下的带宽收益比。关键不在于压得最狠,而在于“谁在什么场景下真正省了流量”。
从日志中提取压缩类型与体积
Nginx 默认不记录响应体大小和编码方式,需显式配置日志格式:
log_format compression_log'$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_accept_encoding" "$sent_http_content_encoding" '
'$request_length $upstream_response_length;
access_log /var/log/nginx/compression.log compression_log;
其中:
• $bytes_sent 是实际发送的字节数(含响应头)
• $upstream_response_length 是后端原始响应体长度(需后端或 proxy_pass 透传,如用 add_header X-Orig-Size $body_bytes_sent; 并在日志中用 $sent_http_x_orig_size 捕获)
• $sent_http_content_encoding 精确反映最终生效的压缩格式(gzip、br、deflate 或空)
按算法分组计算压缩收益
用 awk 或 goaccess 快速统计每种编码的实际节省效果:
awk -F' ' '{
if ($12 == "gzip" && $14 > 0) {
saved += $14 - $8;
total_orig += $14;
}
} END { printf "gzip: %.1f%% saved (%d KB / %d KB)\n", saved/total_orig*100, saved/1024, total_orig/1024 }'
注意:
• 仅对文本类资源(text/html、application/json、text/css)计算才有意义,图片/视频本身已压缩,再压可能增负
• 若日志中无原始大小,可用 $request_length 近似(对小响应较准),或改用 OpenResty 在 Lua 层捕获 ngx.var.upstream_http_content_length
识别高价值压缩场景
带宽收益比高的不是“所有 br”,而是特定组合:
-
移动端 API 响应:Accept-Encoding 含
br且响应为 JSON(>2KB),Brotli 通常比 gzip 多省 12–18% -
Chrome 桌面端 HTML:Accept-Encoding 含
gzip, br但返回gzip,说明服务器未启用 Brotli 或未配优先级,属优化缺口 -
IE11 或旧 Android WebView:Accept-Encoding 只有
gzip,却收到br—— 表示压缩协商失败,可能因 Nginx 配置未 fallback,需检查gzip_disable或brotli_types
避免常见误判
几个容易拉低收益比的坑:
- 未排除 304 响应:
$sent_http_content_encoding在 304 中为空,但$bytes_sent极小,会虚高“节省率”,建议加$status == 200过滤 - 混淆
deflate与gzip:deflate在 HTTP 中实际多指 zlib 格式,浏览器兼容性不如 gzip,若大量出现,需检查是否误配gzip_vary off导致协商异常 - 忽略小响应惩罚:
br对










