Nginx启用Brotli后CPU陡增主因是配置与资源错配:小文件(request_length

当 Nginx 启用 Brotli 后出现 CPU 使用率陡增(尤其是单核 100% 或整体持续 >90%),问题往往不在“Brotli 本身慢”,而在于配置与资源特性的错配。排查重点不是找 bug,而是确认:压缩是否在不该触发时强行执行?是否对小文件、高频接口反复压缩?是否和 gzip 冗余共存?
看日志确认压缩是否被滥用
打开 Nginx 访问日志(或自定义日志格式中加入 $brotli_ratio 和 $request_length),筛选出 CPU 高峰时段的请求:
- 查 brotli_ratio=1 的大量日志:说明 Brotli 跳过压缩,但依然走了压缩判断流程——常见于 brotli_min_length 设置过低(如设为 10)、或 brotli_types 过宽(误含二进制类型)
- 查 brotli_ratio > 1 但 request_length 的请求:小文件压了也省不了多少字节,却白耗 CPU;建议将 brotli_min_length 提至 1024 起步
- 查同一 URL 多次出现不同 brotli_ratio 值:说明响应体动态生成(如 PHP/Node 接口),每次内容不同导致无法复用缓存,又无法启用 brotli_static on,此时应降级压缩级别
检查配置是否存在冗余或冲突
Brotli 和 gzip 共存是 CPU 飙升最常见诱因——Nginx 会为每个请求依次尝试协商、判断、压缩,双倍开销:
- 运行 nginx -T | grep -E "(gzip|brotli)_",确认没同时开启 gzip on 和 brotli on;若必须兼容旧客户端,至少设 gzip off,并靠 CDN 或前端做降级
- 确认 brotli_static 状态:若设为 on,但对应资源缺失 .br 文件,Nginx 不会 fallback,而是静默跳过——看似没压,实则仍执行了 MIME 判断、Accept-Encoding 解析等流程
- 检查 brotli_comp_level 是否过高:动态内容(如 API)设成 7–9 是灾难性的;API 建议用 3–4,静态资源才用 6–7
用压力工具定位真实瓶颈点
别只看 top,要模拟真实请求模式验证:
- 对典型 API 接口(如 /api/status)用 hey -n 1000 -c 100 -H "Accept-Encoding: br" 压测,观察 CPU 和 $brotli_ratio 日志变化趋势;若 ratio 从 2.8 快速跌到 1.2,说明高压下压缩质量崩溃,CPU 却没省下来
- 对比关闭 Brotli 后同样压测:若 CPU 下降 40%+ 且 TTFB 反而更稳,基本锁定是 Brotli 动态压缩引发的资源错配
- 抓包验证协商行为:用 curl -v -H "Accept-Encoding: br,gzip" 请求,确认响应头是 Content-Encoding: br;若返回 gzip 或无压缩头,说明协商逻辑被干扰(如 WAF 清除头、CDN 强制降级)
快速验证与临时缓解方案
无需重启服务即可验证是否为 Brotli 导致:
- 临时禁用:在对应 location 中加 brotli off;,然后 nginx -s reload;若 CPU 瞬间回落,即确认根因
- 限流保底:配合 limit_req 对高危路径(如 /api/)限频,避免小文件高频请求反复触发压缩判断
- 改用静态压缩:对 JS/CSS 等稳定资源,用 webpack 插件预生成 .br 文件,Nginx 配置 brotli_static on;,彻底消除运行时 CPU 开销


















