区分CPU负载与CPU使用率
很多人混淆CPU负载(Load Average)和CPU使用率(CPU Utilization)。Load Average反映的是系统中处于可运行状态(R状态)和不可中断睡眠状态(D状态)的进程队列长度,CPU使用率则是CPU处于非空闲时间的比例。一个4核服务器Load Average为8,意味着每个核平均有2个进程在等待,系统处于过载状态;而CPU使用率100%但Load Average为4(4核)则说明CPU满载但没有积压任务。
排查CPU问题的第一步是明确关注哪个指标:响应变慢看Load Average,资源利用率看CPU使用率。
使用top和htop快速定位高消耗进程
登录服务器后,直接运行top命令:
top - 14:30:25 up 45 days, 3:12, 2 users, load average: 12.5, 8.3, 4.1
Tasks: 234 total, 5 running, 229 sleeping, 0 stopped, 0 zombie
%Cpu(s): 82.3 us, 5.2 sy, 0.0 ni, 10.1 id, 0.0 wa, 2.4 hi, 0.0 si
关键字段解读:
– load average: 12.5, 8.3, 4.1:1分钟/5分钟/15分钟平均负载,数值持续上升说明问题在恶化
– 82.3 us:用户态CPU占比,过高说明应用进程消耗大量CPU
– 5.2 sy:内核态CPU占比,过高可能存在频繁系统调用或上下文切换
– 10.1 id:空闲比例,低于10%需要关注
– 0.0 wa:I/O等待,高wa值说明CPU在等磁盘,问题可能不在CPU
按P键按CPU使用率排序,找到最耗资源的进程PID。
分析进程级别的CPU消耗分布
定位到高CPU进程后,用pidstat细化分析:
pidstat -p <PID> 1 5
# 每秒采样1次,共5次
输出中关注%usr(用户态)、%system(内核态)、%wait(等待CPU时间)。如果%system异常高,检查是否有频繁的锁竞争或系统调用。
对于Java应用,用jstack获取线程dump:
jstack <PID> | grep -A 20 "nid=0x"
对于Go应用,用pprof分析CPU profile:
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
处理Load Average高但CPU使用率低的场景
这种情况通常是D状态(不可中断睡眠)进程堆积导致,最常见的原因是磁盘I/O瓶颈。验证方法:
# 查看D状态进程
ps aux | awk '$8 ~ /D/ {print}'
# 查看磁盘I/O情况
iostat -x 1 5
iostat输出中%util接近100%说明磁盘达到性能极限,await值高说明I/O响应慢。解决方案:升级SSD、优化磁盘写入策略、减少sync操作。
NFS挂载卡死也会导致D状态进程堆积,检查方法:
nfsstat -c # 查看NFS客户端统计
mount | grep nfs # 查看NFS挂载点
# 临时修复:强制卸载卡死的NFS
umount -f /mnt/nfs_share
上下文切换与锁竞争排查
当sy(内核态CPU)占比异常高时,重点排查上下文切换:
# 查看上下文切换频率
vmstat 1 5
# 关注 cs 列(每秒上下文切换次数)
# 超过100000次/秒属于异常
进一步用perf分析内核热点:
perf top -g
# -g 显示调用链,定位内核消耗在哪个函数
常见的锁竞争场景:多个线程争抢同一把mutex,导致频繁的futex系统调用。通过perf report可以看到__lll_lock_wait或mutex_spin函数占比高。
解决方案:将粗粒度锁拆分为细粒度锁,或改用读写锁、无锁数据结构。
CPU亲和性与调度优化
对于NUMA架构服务器,进程在多个NUMA节点间迁移会导致远程内存访问延迟。用numactl绑定进程到指定NUMA节点:
# 查看NUMA拓扑
numactl --hardware
# 绑定到node 0
numactl --cpunodebind=0 --membind=0 java -jar app.jar
对于中断处理,将网卡中断绑定到特定CPU核,避免中断风暴影响业务线程:
# 查看中断分布
cat /proc/interrupts | grep eth
# 设置IRQ亲和性(将中断绑定到CPU 0-3)
echo 0f > /proc/irq/32/smp_affinity
通过irqbalance服务也可以自动均衡中断分配,但对于高性能场景手动绑定效果更好。
长期监控与告警配置
临时排查解决不了持续性问题。部署Prometheus + node_exporter采集CPU指标,配置告警规则:
# Prometheus告警规则示例
- alert: HighCpuLoad
expr: node_load15 / count(node_cpu_info{mode="idle"}) by (instance) > 2
for: 10m
labels:
severity: warning
annotations:
summary: "CPU load high"
Load Average超过核数2倍持续10分钟触发告警,提前介入避免服务降级。配合Grafana看板可直观观察负载趋势和周期性波动规律。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/linux-fu-wu-qi-cpu-fu-zai-yi-chang-pai-cha-yu-xing-neng/