关键在于确认响应变慢是否由对应worker进程CPU激增直接导致,需通过CPU亲和性绑定、PID级CPU监控与access.log请求耗时时间对齐分析。

绑定 worker 到独立 CPU 核心
避免多个 worker 在同一核心争抢调度,干扰 CPU 数据归属。例如 4 核服务器配置:
worker_cpu_affinity 0001 0010 0100 1000;
同时设 worker_processes 4;,确保每个 worker 独占一个物理核。这样后续采集到的 CPU 数据才能明确对应到具体 worker 处理的请求。
采集可对齐的粒度数据
不能只看 top 里 “nginx” 进程整体 CPU,而要落到单个 worker PID:
- 用 ps -o pid,comm,%cpu,psr -C nginx 查每个 worker 的 PID、CPU 占比、运行在哪颗 CPU 上(psr 字段),验证 affinity 是否生效;
- 对关键 PID 执行 pidstat -p PID 1,每秒输出一次 CPU 使用率,生成带时间戳的序列;
- 同步采集 access.log 中的 $request_time 和 $upstream_response_time,并记录日志时间戳($time_local);
- 将 pidstat 时间戳与日志时间戳按秒对齐(注意时区与系统时间一致性),就能看出:某秒内某个 worker CPU 达到 85%,同时该 worker 处理的请求中,有多个 $request_time > 500ms,且 $upstream_response_time 很小(比如
用可控流量验证因果关系
单纯观察曲线容易误判。需做三级对照实验:
- 关闭所有压缩:gzip off; brotli off;,跑 5 分钟,记下各 worker CPU 基线;
- 开启中等压缩:gzip_comp_level 6;,用 wrk 对固定接口压测(如 200 QPS,返回体 ≥2KB),再跑 5 分钟;
- 切换为高压缩:gzip_comp_level 9;,保持相同流量,再跑 5 分钟;
- 每次 reload 后等待 10 秒,确保连接平稳过渡;
- 对比三条 CPU 曲线,若某 worker 在高压缩阶段 CPU 显著跃升,且其处理的请求 $request_time 同步拉长,而 $upstream_response_time 几乎不变,即可确认压缩是主因。
排除干扰项,聚焦真实瓶颈
响应时间变长不等于 CPU 高——也可能是锁竞争、IO 等待或配置不当:
- 检查 worker_rlimit_nofile 和系统 ulimit,避免因文件描述符不足触发阻塞;
- 确认未启用冗余模块(如未使用的第三方 filter),它们可能隐式消耗 CPU;
- 观察 connections_writing 是否持续高位,结合 $request_time 与 $upstream_response_time 差值大,可能指向 sendfile 或 gzip_buffer 不足导致多次拷贝;
- 若 CPU 高但 $request_time 并不长,可能是大量短连接反复建立销毁,此时应查 keepalive_requests 和客户端行为。


















