平滑升级nginx并保留brotli需重新编译集成ngx_brotli模块,用usr2/winch/quit信号热切换,并在nginx.conf中显式加载模块、启用brotli且关闭gzip,最后通过curl验证content-encoding: br生效。

要在升级 Nginx 版本时平滑保留 Brotli 压缩功能,关键不是“保留模块”,而是**在新二进制中重新集成 ngx_brotli 模块,并通过信号机制完成热切换**。Brotli 不是运行时插件,它依赖 libbrotli 和动态模块支持,必须随 Nginx 一起编译;直接复制旧模块.so 文件或跳过编译步骤会导致加载失败或崩溃。
先确保新 Nginx 编译含 Brotli 支持
升级前不单独安装模块,而是在编译新版本时一并集成:
- 确认已安装 libbrotli 开发库:执行
sudo ldconfig -p | grep brotli,应看到libbrotlienc.so.1和libbrotlidec.so.1;若缺失,需从源码编译安装并运行sudo ldconfig - 拉取与目标 Nginx 版本匹配的
ngx_brotli源码(例如 Nginx 1.26.x 对应其 master 分支),进入该目录执行git submodule update --init - 进入 Nginx 源码目录,用
nginx -V输出的原始 configure 参数,追加:--add-dynamic-module=/path/to/ngx_brotli --with-compat
注意:不能漏掉--with-compat,否则动态模块无法加载 - 执行
make(不要make install),生成objs/ngx_http_brotli_filter_module.so
升级后正确加载模块并启用压缩
替换二进制只是第一步,模块需显式声明和配置才能生效:
- 将生成的
.so文件复制到 Nginx 模块目录(如/usr/local/nginx/modules/) - 在
nginx.conf最开头添加:load_module modules/ngx_http_brotli_filter_module.so; - 在
http块中配置 Brotli(注意关闭 gzip 冲突):brotli on;<br> brotli_comp_level 4;<br> brotli_types text/plain text/css application/javascript application/json;<br> gzip off;
- 执行
nginx -t验证语法,再发信号升级
用 USR2/WINCH/QUIT 完成零中断切换
仅替换二进制文件不等于平滑升级;必须通过进程信号让新旧 master 协同工作:
- 备份旧二进制:
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old - 覆盖新二进制:
cp objs/nginx /usr/local/nginx/sbin/nginx,检查权限一致 - 发送
kill -USR2 $(cat /usr/local/nginx/logs/nginx.pid)—— 启动新 master,此时nginx.pid.oldbin出现 - 发送
kill -WINCH $(cat /usr/local/nginx/logs/nginx.pid)—— 旧 worker 逐步退出,不再接新请求 - 确认旧 worker 全部消失后,发送
kill -QUIT $(cat /usr/local/nginx/logs/nginx.pid.oldbin)—— 终止旧 master
验证 Brotli 是否真正生效
别只看配置是否加载成功,要实测响应头:
- 用 curl 请求一个 JS 或 CSS 资源:
curl -H "Accept-Encoding: br" -I https://your-site.com/app.js - 响应头中必须包含:
Content-Encoding: br
且Content-Length明显小于未压缩时 - 若返回
gzip或无Content-Encoding,说明gzip off没起作用,或brotli on位置错误(必须在 http 块内)











