在 Nginx 反向代理场景下,开启 gzip 压缩不仅能减少带宽占用,还能加快客户端接收速度。但默认配置下 Nginx 不会压缩代理回来的内容,必须正确配置 gzip_proxied 指令并确保上游未重复压缩。
先说结论:需在 Nginx 配置中显式开启 gzip_proxied 并添加 gzip_vary 以适配缓存。
- 适合:文本、JSON、CSS、JS 等可压缩资源,不适合图片视频
- 前置检查:确认后端服务未开启 gzip,避免二次压缩
- 验收:通过 curl -v 检查响应头 Content-Encoding 是否为 gzip
核心配置示例
以下是最小可用的配置片段,放入 http 或 server 块中。注意增加了 gzip_vary on; 以告知缓存服务器内容已压缩。
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
gzip_proxied any;
gzip_min_length 1000;
gzip_vary on;配置原理与上游检查
Nginx 的 gzip 模块默认只压缩直接生成的内容。当 Nginx 作为反向代理时,响应内容来自上游服务器,默认被视为“已代理”内容。出于兼容性和性能考虑,Nginx 默认不压缩这些内容,除非明确告知它可以通过 gzip_proxied 指令进行压缩。
关键风险:配置 gzip_proxied any; 后,Nginx 会尝试压缩所有代理响应。如果上游服务器(如 Tomcat、Spring Boot)已经开启了 gzip,Nginx 可能会对已压缩的数据再次处理,导致 CPU 浪费且文件体积不变甚至变大。
排查步骤:在开启 Nginx 压缩前,先直接请求上游服务,检查响应头是否已有 Content-Encoding: gzip。如果有,请关闭上游的压缩功能,仅保留 Nginx 层面的压缩。
生效验证
使用 curl 命令模拟请求,检查响应头。建议使用 -v 参数而非 -I,因为 HEAD 请求在某些服务端配置下可能不返回完整的 Content-Encoding 头。
curl -H "Accept-Encoding: gzip" -v http://你的域名 2>&1 | grep Content-Encoding观察输出中是否包含 Content-Encoding: gzip。如果没有,检查后端返回的 Content-Type 是否在 gzip_types 列表中,或者内容长度是否小于 gzip_min_length。
常见风险与排查
1. 重复压缩:不要对已经压缩过的文件(如 jpg, png, mp4)开启 gzip,这只会浪费 CPU 且几乎不减小体积。务必确认上游未开启压缩。
2. 缓存兼容:开启压缩后,响应内容会变化,配置 gzip_vary on; 会在响应头添加 Vary: Accept-Encoding,确保缓存机制能区分压缩与未压缩版本。
3. 小文件阈值:过小的文件压缩后体积可能反而变大,建议设置 gzip_min_length 阈值,例如 1k 以上。
4. 代理缓冲:如果 upstream 响应较慢,确保 proxy_buffering 开启,否则 gzip 可能无法有效缓冲后再压缩。