服务器CPU占用100%怎么排查?从top到perf的全链路诊断路径
监控面板跳出CPU 100%告警的那一刻,很多人的第一反应是“配置不够了,该升级了”。但根据我们处理用户问题的经验,CPU跑满的原因至少分四种:进程死循环、IO等待导致的假性跑满、配置参数不合理、以及被CC攻击。不区分原因就升级配置,等于花钱买心安,问题还在。
这篇按实际排查顺序走一遍。从最基础的top命令开始,逐步深入到进程级、线程级、系统调用级,每一步都告诉你命令在找什么、看到什么结果说明什么问题。
第一步:用top确认“谁在吃CPU”
登录服务器后,第一件事是执行:
top
关注三个地方。第一行的load average,如果三个数值(1分钟、5分钟、15分钟)都高于CPU核心数,说明系统确实在超负荷运转。第三行的%Cpu(s),重点看us(用户空间)、sy(内核空间)、wa(IO等待)三个值。如果wa超过20%,问题很可能不在CPU本身,而在磁盘IO。
再往下看进程列表,按 P 键可以按CPU占用排序。找到占用最高的进程,记下它的PID和COMMAND。
如果你想要更直观的界面,可以装htop:
apt install htop && htop
htop的彩色进度条能让你一眼看出哪个核心在跑满。但要注意,htop不一定是所有服务器都预装的,top才是通用工具。如果你还不确定自己的服务器上装了哪些工具,可以先去优币云博客看看我们整理的常用软件清单。
第二步:用pidstat追踪进程的CPU消耗趋势
top只能告诉你“此刻”谁在吃CPU。如果进程是间歇性跑满,top可能抓不到。这时候用pidstat更合适:
pidstat -u 1 5
这个命令会每秒采样一次,连续输出五次。输出的%CPU列会显示每个进程在采样周期内的CPU占用。如果某个进程的%CPU持续超过100%,说明它是多线程程序,在多个核心上同时运行。
更进一步,用 -t 参数可以看到线程级别的消耗:
pidstat -u -t -p <PID> 1 5
这个命令会列出该进程下所有线程的CPU占用。Java应用尤其需要这一步——很多时候是某个GC线程在疯狂工作,而不是业务线程。
第三步:判断是“真跑满”还是“假跑满”
CPU 100%不一定是CPU不够用。Linux的CPU占用统计中,wa(IO等待)也算在“非空闲”里。如果wa很高,进程其实在等磁盘读写或网络响应,CPU本身是空闲的。
用iostat确认IO状态:
iostat -x 1 5
重点看 %util 列,如果某个磁盘的%util接近100%,说明磁盘是瓶颈。再看 await 列,如果平均值超过20ms,IO响应明显偏慢。
另一种“假跑满”是sy(内核空间)占比过高。如果sy超过30%,说明系统调用太频繁,可能是某个程序在反复创建销毁进程,或者网络包处理占用了大量CPU。这时候用 vmstat 1 看 cs(上下文切换次数)和 in(中断次数),如果cs每秒超过10万,说明上下文切换是瓶颈。
第四步:用sar看历史趋势,判断是突发还是持续
如果你登录服务器的时候CPU已经恢复正常了,top和pidstat都抓不到现场。这时候sar就派上用场了:
sar -u -f /var/log/sysstat/sa$(date +%d) | tail -50
sar会读取历史采样数据,显示过去某段时间的CPU使用情况。你可以看到CPU是什么时候开始跑满的、持续了多久、峰值出现在哪个时段。这个信息对于判断是定时任务触发还是持续性问题非常关键。
如果sar没有数据,说明sysstat服务没启动。执行 systemctl start sysstat && systemctl enable sysstat 即可开启。建议在服务器部署初期就装上,别等到出问题才发现没数据可查。
第五步:perf定位到具体函数
如果前面的步骤确认了某个进程确实在持续消耗CPU,下一步是搞清楚它到底在执行什么代码。perf是Linux下最强大的性能分析工具:
perf top -p <PID>
这个命令会实时显示该进程的热点函数。你不需要看懂每一行汇编,只要找到占用百分比最高的那几个函数名,就能大致判断问题方向。比如看到 malloc 或 free 频繁出现,说明内存分配有问题;看到 memcpy 占比很高,说明有大量数据拷贝。
如果perf提示权限不足,需要在 /proc/sys/kernel/perf_event_paranoid 中调整权限等级。这个操作需要root权限,修改前建议先确认服务器上没有其他安全限制。
第六步:strace跟踪系统调用
当perf的输出不够直观时,strace可以告诉你进程在系统调用层面做了什么:
strace -c -p <PID>
按 Ctrl+C 中断后,strace会输出一个统计表,列出每个系统调用的次数和耗时。如果某个调用(比如 read 或 write)的次数异常高,说明进程在反复读写文件或网络。如果 futex 调用次数很多,说明进程在等锁,可能存在线程竞争问题。
strace会对进程性能产生一定影响,建议只在排查时短暂使用,定位到问题后立即停止。
常见场景与对应处理方式
| 现象 | 可能原因 | 处理方向 |
|---|---|---|
| 单进程%CPU持续>100% | 死循环、GC频繁、代码bug | 检查该进程的日志,必要时重启或回滚版本 |
| wa>20%且iostat %util接近100% | 磁盘IO瓶颈 | 检查是否有大量文件读写,考虑升级SSD或优化查询 |
| sy>30%且cs很高 | 系统调用频繁、上下文切换过多 | 用perf定位热函数,检查是否线程数配置过大 |
| 多个进程同时跑满CPU | CC攻击、被入侵 | 检查网络连接数,用netstat查看异常IP |
| 负载突然飙升后恢复 | 定时任务、日志切割 | 检查crontab和日志轮转配置 |
如果确认是CC攻击导致的CPU跑满,普通服务器很难扛住。优币云的高防服务器系列自带DDoS和CC防护,从基础款到企业款都有覆盖,适合电商和游戏这类容易被盯上的业务。具体配置可以参考我们的海外服务器选购指南。
CPU 100%只是一个信号,不是问题本身。排查的核心是回答“谁在吃CPU”和“为什么吃CPU”这两个问题。top告诉你谁,pidstat和sar告诉你什么时候,perf和strace告诉你为什么。这套流程走下来,大部分问题都能在五分钟内定位到根因。
如果你在排查过程中发现确实是配置不够用了,可以先去产品列表看看优币云的服务器方案,从香港节点到美国节点都有从1核1G到8核16G的选项。如果是团队或企业用户,多IP服务器和高防服务器也能覆盖更复杂的业务场景。遇到具体问题可以访问常见问题页面,或者直接联系我们协助排查。