Linux下Load Average高不等于CPU忙,它统计就绪态与D状态进程数;需先用nproc查核数、1分钟load除以核数>1才说明真超载,再分四步排查:①看top中us/sy/wa/st定位瓶颈类型;②用ps/proc/loadavg/stack查D状态进程;③用pidstat/top -Hp/strace定位真实CPU消耗线程或系统调用;④检查句柄泄漏、内核参数、磁盘健康及软中断分布等隐蔽干扰。

Linux下Load Average高,不等于CPU真忙——它统计的是“就绪态 + 不可中断态(D状态)”进程的平均数量,和CPU使用率是两回事。先看负载值是否真超标:用 nproc 查逻辑核数,再拿1分钟load除以核数,结果>1才说明有排队压力。
第一步:区分是CPU真忙,还是假高负载
打开 top,盯紧顶部这三行关键指标:
- %Cpu(s) 行中的 us:高于70%且持续,大概率是应用代码在密集计算(比如死循环、加解密、正则回溯)
- sy 高 + us 低:内核态耗时多,常见于频繁系统调用(epoll_wait、fork、sendfile)、软中断(网卡收包)、或容器cgroup配额限制触发调度开销
- wa 高(>5%):CPU在等磁盘或网络IO,此时load高但CPU idle可能还很高,本质是I/O瓶颈,不是CPU问题
- st 高(仅虚拟机):宿主机抢资源,需联系云厂商查底层超分或争抢情况
第二步:确认有没有大量D状态进程拖累load
D状态进程卡在内核态等IO或锁,不占CPU但计入load,是“高load低CPU”的最常见原因:
- 运行 ps aux | awk '$8 ~ /D/ {print}',看是否有NFS挂载点假死、磁盘响应超时、或驱动异常导致的长期D进程
- 配合 cat /proc/loadavg 看第4字段(当前运行队列长度)和第5字段(总进程数),若前者小、后者大,D进程占比很可能高
- 对可疑PID执行 ls -l /proc/[PID]/stack,能直接看到它卡在哪条内核路径上(如 waiting_for_completion、nfs_wait_on_request)
第三步:定位真实CPU消耗源头
别只信top里进程级%CPU——Java/Go常有单线程打满而整体进程不显眼:
- 用 pidstat -u 1 3 每秒采样,精准抓波动峰值,关注 %usr 和 %sys 列
- 对高消耗进程,执行 top -Hp [PID],按P排序,记下高占用线程TID
- Java服务:把TID转十六进制(printf "%x\n" [TID]),再到 jstack [PID] 日志里搜 nid=0x...,定位到具体方法栈
- 通用分析:用 strace -p [PID] -c -T 2>&1 | grep -E "(futex|epoll_wait|read|write)",futex高=锁竞争,epoll_wait久=连接风暴或后端失联
第四步:检查隐蔽但高频的干扰项
很多case查到最后,问题不在业务代码,而在系统配置或硬件层面:
- 文件句柄泄漏:lsof -p [PID] | wc -l 超过 ulimit -n 限制(默认常为65535),会导致新建连接失败、日志写不进,现象像“无报错但功能卡顿”
- 内核参数过小:net.core.somaxconn 太低会让新连接排队;vm.swappiness=100会激进swap,引发kswapd0狂刷IO推高load和sy%
- 磁盘健康告警:smartctl -a /dev/sdX 查 Reallocated_Sector_Ct、Current_Pending_Sector,坏扇区增多会导致单次IO响应飙升,iostat中await>50ms就是强信号
- 软中断不均:watch -n 1 'cat /proc/softirqs' 看 NET_RX 是否远高于其他项,再结合 cat /proc/interrupts | grep eth 确认网卡中断是否全压在一个CPU核上











