nginx响应体压缩由ngx_http_gzip_module模块在worker process处理请求时实时执行,需同时满足accept-encoding头、gzip开启、匹配types、≥min_length、http版本达标及未被disable排除等条件,压缩后添加content-encoding和vary头,并受comp_level、buffers等配置影响性能。

Nginx 的响应体压缩不是由 worker process 单独“实现”的,而是由 ngx_http_gzip_module 模块在每个 worker process 处理请求时实时执行的过滤操作。worker process 本身不决定是否压缩,它只是执行配置好的压缩逻辑——也就是说,压缩是 Nginx 请求处理流水线中一个标准的、可插拔的过滤阶段,由所有活跃的 worker 进程并行承担。
压缩发生在 worker process 的请求响应阶段
当一个请求进入 Nginx,被某个 worker process 接收并完成 upstream 代理(如转发给后端服务)后,若响应满足以下全部条件,该 worker 就会在发送响应前调用 gzip 过滤器:
- 客户端请求头含
Accept-Encoding: gzip - Nginx 配置启用了
gzip on - 响应 Content-Type 匹配
gzip_types中声明的类型(例如application/json) - 响应体大小 ≥
gzip_min_length(如1024字节) - HTTP 版本 ≥
gzip_http_version(默认1.1) - 未被
gzip_disable规则排除(如旧版 IE)
此时,worker process 会:
- 分配内存缓冲区(由
gzip_buffers控制,如32 4k) - 调用 zlib 库对响应体做流式 gzip 压缩
- 修改响应头:添加
Content-Encoding: gzip和Vary: Accept-Encoding(若开启gzip_vary) - 将压缩后的二进制数据写入 socket 发送给客户端
⚠️ 注意:压缩是 CPU 密集型操作。多个 worker 并发执行时,CPU 使用率会上升——因此需合理设置
gzip_comp_level(推荐 4~6),避免单个请求占用过多时间影响吞吐。
为什么不能靠增加 worker 数量来“加速压缩”?
- 压缩是每个响应独立进行的,不是跨 worker 协作任务
- 增加
worker_processes只提升并发连接承载能力,不降低单次压缩耗时 - 若 CPU 已接近满载,盲目增 worker 反而加剧争抢,导致整体延迟上升
真正影响压缩性能的关键配置是:
-
gzip_comp_level 4;—— 平衡压缩率与 CPU 开销 -
gzip_min_length 1024;—— 跳过小响应,避免“越压越大” -
gzip_buffers 16 8k;—— 避免频繁内存分配(尤其大响应)
压缩与 sendfile、静态文件的关系
-
动态响应(如 JSON 接口):必须启用
gzip on,且依赖gzip_types application/json,由 worker 实时压缩 -
静态文件(如 .js/.css):若启用
sendfile on,Nginx 会绕过用户态直接零拷贝发送——此时 gzip 不生效(因为没经过应用层过滤器)- 解决方案:预压缩静态文件为
.gz,配合ngx_http_gzip_static_module模块自动提供;或禁用sendfile(不推荐,影响性能)
- 解决方案:预压缩静态文件为
高频接口场景下的关键实践
- 后端框架(Spring Boot / FastAPI)必须关闭自身压缩,只留 Nginx 一层
- 显式配置
gzip_types application/json text/plain;,不依赖默认值 - 必须设
gzip_vary on;,防止 CDN 缓存混淆压缩/未压缩版本 - 不建议对
image/*、video/*、application/octet-stream等已压缩格式启用 gzip
不复杂但容易忽略。











