Linux CPU 占用过高怎么排查top、ps、pidstat1. 前言Linux 服务器 CPU 占用过高是线上排障中非常常见的问题。常见现象包括接口响应变慢SSH 登录卡顿服务线程堆积负载 Load Average 升高风扇转速变高进程占用 CPU 长时间不下降。排查 CPU 问题不能只看一个top。更合理的方式是结合top ps pidstat uptime mpstat perf 应用日志本文重点围绕top、ps、pidstat展开讲清楚 Linux CPU 占用过高时怎么定位到具体进程、线程和可能原因。2. CPU 占用高可能是什么原因CPU 高并不一定是坏事。如果服务器正在正常处理大量请求CPU 高可能是正常负载。但如果 CPU 持续高位就要重点排查。常见原因类型说明业务请求量突增流量变大服务正常忙死循环某段代码一直空转线程池打满大量线程争抢 CPUGC 频繁Java 程序频繁垃圾回收正则或加密计算过重CPU 密集型任务日志疯狂打印大量字符串拼接和 IO异常进程挖矿、木马、未知脚本系统中断高网卡、磁盘、驱动异常所以排查时要先判断是哪个进程高 是用户态 CPU 高还是系统态 CPU 高 是单线程高还是多线程高 CPU 高是否和业务流量一致3. top第一时间看整体情况执行top重点看顶部几行%Cpu(s): 85.0 us, 10.0 sy, 0.0 ni, 3.0 id, 1.0 wa, 0.0 hi, 1.0 si, 0.0 st字段说明字段含义us用户态 CPU业务程序代码消耗sy系统态 CPU内核调用消耗id空闲 CPUwa等待 IOhi硬中断si软中断st虚拟化环境中被宿主机偷走的 CPU判断思路现象可能方向us高应用程序计算多、死循环、GC、业务压力大sy高系统调用多、网络/文件操作频繁wa高磁盘 IO 慢不一定是 CPU 真忙hi/si高网络包、中断、驱动相关问题st高云主机宿主机资源争抢4. top 中按 CPU 排序进入top后按P可以按 CPU 占用排序。常见字段字段说明PID进程 IDUSER进程用户%CPUCPU 占用%MEM内存占用TIME累计 CPU 时间COMMAND命令名如果某个进程长期排第一基本就是重点对象。查看某个进程详细信息ps -fp PID例如ps -fp 123455. ps快速找 CPU 最高的进程查看 CPU 占用最高的前 10 个进程ps aux --sort-%cpu | head输出示例USER PID %CPU %MEM COMMAND app 1234 180 20.1 java -jar app.jar root 2345 60 1.2 nginx说明%CPU可能超过 100多核 CPU 下一个进程多线程可以占用超过 100%。查看指定进程ps -p 1234 -o pid,ppid,user,%cpu,%mem,etime,cmd字段说明字段含义pid进程 IDppid父进程 ID%cpuCPU 占用%mem内存占用etime运行时长cmd启动命令6. pidstat持续观察进程 CPUpidstat来自sysstat工具包。安装Ubuntu / Debiansudo apt install sysstat -yCentOS / RHELsudo yum install sysstat -y查看所有进程 CPU每 1 秒一次pidstat 1查看指定进程pidstat -p 1234 1输出示例UID PID %usr %system %guest %wait %CPU CPU Command app 1234 80.0 10.0 0.0 0.0 90.0 1 java字段说明字段含义%usr用户态 CPU%system系统态 CPU%wait等待 CPU 调度%CPU总 CPU 占用CPU当前运行在哪个 CPU 核心pidstat比top更适合连续观察趋势。7. 定位到线程级别有些进程内部有很多线程。例如 Java、Nginx、MySQL 都可能是多线程或多进程模型。查看某进程的线程 CPUtop -H -p 1234或者ps -mp 1234 -o THREAD,tid,time,%cpu找到占用高的线程 TID 后如果是 Java 程序可以把 TID 转成十六进制printf %x\n 线程ID例如printf %x\n 5678然后用jstack 1234 | grep -A 30 十六进制线程ID定位 Java 线程堆栈。8. mpstat看每个 CPU 核心如果怀疑单核打满可以用mpstat -P ALL 1如果某一个 CPU 核心长期 100%可能是单线程程序跑满中断集中在某个核心线程绑定 CPU某个热点线程异常。9. CPU 高的实战排查流程9.1 看整体 CPUtop重点看us sy wa hi si st9.2 找最高进程ps aux --sort-%cpu | head9.3 持续观察pidstat -p PID 19.4 看线程top -H -p PID9.5 查日志和应用状态journalctl -u 服务名 -n 100 tail -f app.log9.6 如果是 Javajstack PID jstat -gcutil PID 1000看是否频繁 GC 或线程死循环。10. 常见场景判断10.1 用户态 CPU 高top中us高。常见原因业务计算量大死循环大量 JSON 序列化加密解密正则匹配Java GC大量请求。处理思路找进程 找线程 看代码堆栈 看接口流量 看日志10.2 系统态 CPU 高sy高。常见原因大量系统调用网络连接频繁创建关闭文件 IO 很频繁容器或内核网络开销进程频繁 fork。可以结合strace -p PID观察系统调用。线上使用strace要谨慎避免影响进程。10.3 iowait 高wa高不代表 CPU 真忙。它通常表示 CPU 在等磁盘 IO。继续排查iostat -x 1 iotop如果磁盘很忙要去看 IO 问题而不是只盯 CPU。11. 不要一上来 kill -9发现 CPU 高后不建议直接kill -9 PID除非已经确认是异常进程。更稳妥先记录现场保存日志查看进程命令查看线程必要时 dump再考虑重启或 kill。Java 程序可以先jstack PID jstack.txt jmap -histo PID histo.txt然后再处理。12. 小结CPU 高排查核心命令top ps aux --sort-%cpu | head pidstat -p PID 1 top -H -p PID mpstat -P ALL 1排查思路先看整体 CPU 类型 ↓ 找出高 CPU 进程 ↓ 持续观察进程趋势 ↓ 定位到线程 ↓ 结合应用日志和代码堆栈 ↓ 判断是流量、死循环、GC、IO 还是异常进程CPU 排查最重要的是不要只看表面占用率而要判断 CPU 时间到底消耗在用户态、系统态、IO 等待还是中断上。