要观察压缩对Nginx worker CPU的影响,需绑定worker到独立CPU核心、采集单进程CPU数据、设计关闭/中等/高压缩三级对照实验,并通过带压缩比的日志与pidstat时间戳关联分析。

要观察压缩任务对 Nginx worker 进程 CPU 占用的影响,关键不是“配置监控压缩任务”,而是建立一套可比、可归因的观测链:把压缩行为(Gzip 或 Brotli)和具体 worker 进程的 CPU 使用率关联起来,并排除其他干扰因素。
明确压缩与 CPU 的绑定关系
Nginx 本身不为“压缩任务”单独调度线程或进程。所有压缩操作(gzip_comp_level、brotli_filter)都在处理请求的 worker 进程内同步执行,属于该 worker 的 CPU 时间消耗。因此,监控对象就是每个 worker 进程的 CPU 使用率,而非抽象的“压缩任务”。
需确保:
- 已启用 worker_cpu_affinity,让每个 worker 绑定到独立 CPU 核心(如 4 核服务器设为
0001 0010 0100 1000),避免多进程争抢同一核心导致数据混杂; - 使用
worker_processes auto或明确设为 CPU 核心数,使 worker 数量与物理核心对齐; - 禁用可能导致 CPU 波动的非必要模块(如未启用的第三方 filter、冗余日志格式)。
采集粒度精确的 per-worker CPU 数据
系统级工具(如 top、htop)默认按进程名聚合,无法区分多个 nginx worker。应使用以下方式获取单个 worker 的 CPU 耗时:
-
ps -o pid,comm,%cpu,psr -C nginx:显示每个 nginx 进程 PID、CPU 占用率(%cpu)、运行在哪个 CPU 核心(psr),配合worker_cpu_affinity可一一对应; - 结合
pidstat -p PID 1(每秒采样指定 PID),输出稳定时间序列,适合绘图; - 若使用 Prometheus + nginx-lua-prometheus 或 nginx-module-vts,需额外通过 Lua 脚本读取
/proc/PID/stat中的utime+stime字段,计算每秒增量并暴露为指标(如nginx_worker_cpu_seconds_total{pid="12345",cpu="0"})。
触发可控压缩流量用于对比验证
单纯看曲线无法判断波动是否由压缩引起。必须设计对照实验:
- 关闭压缩:
gzip off;+brotli off;,运行 5 分钟,记录各 worker CPU 基线; - 开启压缩(如
gzip_comp_level 6;+gzip_types application/json text/css;),用ab或wrk对大文本响应接口施加稳定 QPS(例如 200 QPS,响应体 ≥2KB),持续 5 分钟; - 切换为高阶压缩(
gzip_comp_level 9;),保持相同流量,再测 5 分钟; - 每次切换后执行
nginx -s reload并等待 10 秒,确保新配置生效且连接平稳过渡。
此时对比三条曲线,就能看出压缩级别提升带来的 CPU 上升幅度是否线性、是否存在某 worker 突然飙升(可能因 affinity 配置错误或负载不均)。
关联压缩日志与 CPU 时间戳
启用带压缩指标的日志格式,将 CPU 波动锚定到具体请求批次:
log_format compress_log '[$time_local] $remote_addr "$request" $status $body_bytes_sent ' 'gzip_ratio=$gzip_ratio brotli_ratio=$brotli_ratio ' 'upstream_response_time=$upstream_response_time request_time=$request_time';
配合 pidstat 输出的时间戳(精确到毫秒),可筛选出 CPU 高峰前后 1 秒内的 access log,检查:
- 是否集中出现大量
gzip_ratio=1.8或brotli_ratio=2.5的请求; - 这些请求的
request_time是否明显高于平均值(说明压缩耗时); - 是否集中在某个特定 PID 的日志中(验证 affinity 是否生效)。


















