
收到CPU告警时,核心不是立刻杀进程或重启服务,而是5分钟内锁定“谁在吃CPU”以及“它在干什么”。关键不在总使用率数字,而在时间分布和上下文——比如是用户态狂跑代码,还是内核态卡在锁或中断里。
CPU高?先看负载和时间分布
单看top显示98%没意义。要结合三个指标交叉判断:
- uptime:看三段平均负载(1/5/15分钟),对比服务器CPU逻辑核数。例如16核机器,load average超20且持续上升,说明确实过载
- vmstat 1 5:重点盯us(用户态)、sy(系统态)、wa(I/O等待)三列。若us长期>80%,大概率是业务代码问题;sy突增则指向内核调用异常;wa高但CPU满,往往背后是磁盘或网络延迟拖垮了调度
- pidstat -u 1 5:比top更稳,能避开交互模式干扰,输出精确到毫秒的CPU采样,适合脚本化采集
定位到进程后,必须下钻到线程级
Java或高并发服务常出现“一个进程占30% CPU,但其实是20个线程各占1.5%”,不看线程会漏掉根因:
- 用top -Hp PID列出该进程所有线程,按P排序找Top 1线程
- 把线程PID转成16进制:printf "%x\n" 线程PID
- 用jstack PID | grep -A10 16进制ID(Java)或perf top -p PID(通用)匹配堆栈,确认它卡在哪个方法或系统调用上
区分用户态高还是系统态高
us高和sy高,排查路径完全不同:
- us高(如Java、Python进程):检查是否死循环、正则回溯、GC频繁(用jstat -gcutil PID 1000 5验证)、或日志全量打印(IO打满导致线程阻塞假象)
- sy高(内核态占比>30%):运行vmstat 1看cs(上下文切换)是否飙升;查cat /proc/interrupts确认是否有某CPU核心中断严重不均;用dmesg -T | tail -20排除硬件报错或OOM Killer日志
别忽略隐性竞争和配置陷阱
有些CPU飙高不来自代码,而来自资源争用或误配:
- 线程数超限:cat /proc/PID/limits | grep "max processes",对比应用实际创建线程数
- 文件描述符耗尽导致accept()失败重试,空转消耗CPU:用lsof -p PID | wc -l与ulimit -n比对
- cgroup限制被突破或未启用,导致单个服务吃光整机资源;可用cat /proc/PID/cgroup确认归属








