Linux 高负载排查与优化策略

2次阅读

是正常的,尤其在多核cpu上;top默认显示所有核心累计占用率,4核满载可达400%;应关注线程级cpu时间消耗及load average与核心数的比值,而非单纯百分比。

Linux 高负载排查与优化策略

top 里 %CPU 超过 100% 是正常的吗?

是正常的,尤其在多核 CPU 上。top 默认显示的是“所有 CPU 核心累计占用率”,所以 4 核机器满载时能看到 %CPU 达到 400%。别一看到 237% 就以为进程疯了。

真正该盯的是单个线程(top -H)或进程的绝对 CPU 时间消耗,而不是百分比本身。

  • top -H -p <pid></pid> 查看某进程下的线程级 CPU 占用,确认是不是某个线程死循环
  • ps -o pid,ppid,thcount,%cpu,comm -p <pid></pid> 看线程数和平均 CPU,快速判断是否线程爆炸
  • 注意 top 右上角的 “Cpu(s)” 行:如果 us(用户态)长期 >70%,说明应用代码或调用库有问题;sy(内核态)高,可能是频繁系统调用、锁竞争或 I/O 等待

load average 三个数字怎么看?

它们不是 CPU 使用率,而是“平均等待队列长度”:1 分钟、5 分钟、15 分钟内,处于 运行态或不可中断睡眠态(D 状态) 的进程平均数量。

关键不是数字大小,而是和 CPU 核心数对比。比如 8 核机器,load average: 9.23 7.65 5.41 意味着过去 1 分钟平均有 1 个进程在排队等 CPU,不算异常;但若持续 >16,就说明系统开始明显争抢资源。

  • uptimecat /proc/loadavg 都能查,后者还附带当前运行进程数和最近使用的 PID
  • 如果 load 高但 %CPU 很低,大概率是大量进程卡在 D 状态(如磁盘 I/O 卡住),用 ps aux --sort=-pcpu | head -10 看不到罪魁祸首,得看 ps aux --sort=-stateD 状态进程
  • 某些 NVMe 或 multipath 设备故障时,会拖住几十个进程在 D 状态,此时 iostat -x 1%util 可能没爆,但 awaitr_await 会飙升到几百毫秒以上

perf record 跑出来一 [unknown] 怎么办?

这是符号缺失导致的——perf 抓到了指令地址,但找不到对应函数名。常见于没装 debuginfo 包、程序是 strip 过的、或者用了 JIT(如 Java/Node.js)。

不解决就只能靠地址猜,基本没法定位热点。

  • centos/RHEL:装 kernel-debuginfo 和对应版本的 *-debuginfo 包(比如 glibc-debuginfo),路径要和 /usr/lib/debug 对齐
  • ubuntu/debian:开 deb-src 源,装 linux-image-$(uname -r)-dbgsymlib<name>-dbg</name> 类包
  • 自己编译的程序:加 -g,别用 strip;Go 程序记得关 -ldflags="-s -w";Node.js 用 --interpreted-frames-native-stack 参数启动才能看到 JS 函数

为什么 iowait 高但磁盘 util 却很低?

因为 iowait 是 CPU 在等 I/O 完成时的空闲时间统计,而 %util 是设备忙的时间占比。两者统计维度不同——前者是 CPU 视角,后者是设备驱动视角。

典型场景:大量小 IO、随机读写、IO 调度器阻塞、或存储层(如 ceph、nfs、overlayfs)引入延迟,都会让 CPU 等很久,但块设备本身可能刚发完请求就返回了,%util 看不出压力。

  • iostat -x 1 重点看 avgqu-sz(平均队列深度)和 await(单次 IO 平均耗时):如果 avgqu-sz > 1await > 10ms(SSD)或 >20ms(HDD),说明 IO 路径有瓶颈
  • iotop -o 找真正发 IO 的进程;pidstat -d 1 看每个进程的读写 BPS 和 IO 等待时间
  • 如果是容器环境,cat /sys/fs/cgroup/blkio/.../blkio.io_service_bytes 可以确认是不是某个容器把 IO 带宽占满了,即使宿主机 iostat 看着不高

高负载排查最易被忽略的点:别只盯着 CPU 和磁盘,/proc/interrupts 里软中断(NET_RXIRQ_TIME_ACCOUNTING)持续飙高,可能意味着网卡收包压垮了单个 CPU 核,这时候调 irqbalance 或手动绑核才管用。

text=ZqhQzanResources