top、pidstat、ps 和 /proc/pressure/cpu 找到热点进程。Linux 虚拟机、测试机或一次性容器,安装 procps、sysstat、stress-ng(可选)。实验必须带 timeout,默认上限 120 秒。
mkdir -p /tmp/lab-cpu
nproc
uptime
which stress-ng || echo "stress-ng 未安装,将使用 yes 作为替代"
如果使用容器,建议加 --cpus=1,这样只会影响容器自己的 CPU 配额:
docker run -d --rm --name lab-cpu --cpus=1 alpine:3.20 \
sh -c 'timeout 120s sh -c "while :; do :; done"'
优先用 stress-ng 启动两个满载 worker,并用 timeout 兜底:
timeout 120s stress-ng --cpu 2 --cpu-load 100 --timeout 110s --metrics-brief &
echo $! > /tmp/lab-cpu/stress.pid
没有 stress-ng 时,用 yes 制造单核满载,同样必须加 timeout:
timeout 120s yes > /dev/null 2>&1 &
echo $! > /tmp/lab-cpu/stress.pid
uptime
top -b -n1 | head -20
ps -eo pid,ppid,comm,%cpu --sort=-%cpu | head -10
pidstat -p "$(pgrep -n stress-ng || pgrep -n yes)" 1 5
cat /proc/pressure/cpu
预期 top 中 stress-ng 或 yes 占用接近 100%(多核机器上可能是若干核),%Cpu(s) 的 us 明显升高,load average 上升,/proc/pressure/cpu 出现 some 或 full 压力值。timeout 到期后进程自动退出。
top -Hp <pid> 看线程级占用;单线程打满和多线程打满的处理方式不同。us 高通常是用户态计算;sy 高看系统调用和内核路径;wa 高是 IO 等待,不是 CPU 忙;st 高是虚拟化被宿主机抢占。cat /sys/fs/cgroup/cpu.max 2>/dev/null || cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us
cat /sys/fs/cgroup/cpu.stat
nr_throttled 和 throttled_usec 增长说明被 CPU 配额限制,表现为“CPU 使用率不高但延迟很高”。
top 看到的 100% 是相对一个核还是整机,必须结合 cpu.max 判断。timeout 自然结束,或手动终止实验进程:kill "$(cat /tmp/lab-cpu/stress.pid)" 2>/dev/null || true
pkill -f 'stress-ng --cpu' 2>/dev/null || true
pkill -x yes 2>/dev/null || true
pgrep -a -f 'stress-ng|yes' || echo "已清理"
perf top、火焰图和线程栈,再决定是优化热点、限流、拆分任务还是扩容。cpu.stat 的节流计数是否下降。nice/renice 或 cgroup 限制,避免影响在线业务。docker rm -f lab-cpu 2>/dev/null || true
rm -rf /tmp/lab-cpu
如果使用宿主机进程,确认 pgrep -a stress-ng 和 pgrep -a yes 都没有残留后再结束演练。
load average 很高但 CPU 使用率很低,可能是什么原因?timeout?cpu.stat 的 nr_throttled 和 throttled_usec,确认是否被 CPU 配额节流。