网站响应突然变慢、SSH 登录卡顿、面板操作半天没反应——这多半是服务器上某个进程把 CPU 吃满了。很多新手的第一反应是直接重启服务器,但重启只能临时缓解,问题往往几小时后复现,因为你根本不知道是哪个进程、为什么占这么高。本文教你如何只用系统自带的 top 与 ps 两个命令,一步步把高 CPU 占用的异常进程找出来,看清它是谁、从哪来、该不该杀。无论你管理的是 VPS(虚拟专用服务器)还是独立服务器,这套排查思路都能帮助你在不重启的情况下解决大部分 CPU 异常问题。

先看负载再谈进程:如何确认 CPU 真的异常
收到告警先别急着找进程,第一步是确认 CPU 压力是否真实存在。登录服务器执行 uptime,会看到三个负载均值(load average),分别对应最近 1 分钟、5 分钟、15 分钟的平均负载。判断标准很简单:负载值持续高于 CPU 核心数就是异常。比如一台 2 核 VPS 的负载长期在 4 以上,说明任务排队严重;如果只是 1 分钟值冲高、15 分钟值正常,通常是一次性脚本跑完就恢复,不必过度紧张。
负载高不一定全是 CPU 的锅,uptime 之后要立即用 top 区分。直接输入 top(部分精简系统需要先 yum install -y procps 或 apt install -y procps),进入交互界面后看两行关键数据:%Cpu(s) 行显示 CPU 时间都花在哪里,us(用户态)占比高说明是某个应用程序在消耗,sy(内核态)高可能是频繁系统调用,wa(等待磁盘 I/O)高则是磁盘瓶颈,此时再高的 CPU 数字也不能靠杀进程解决,重点应转向磁盘与内存状态。按数字键 1 可以展开每个核心的独立占用,多核机器上用它确认是单核被打满还是所有核心均衡升高——前者常见于单进程死循环,后者更可能是流量暴涨或被爬虫扫站。
一个实际案例:某站长反馈网站每天下午三点左右变卡,uptime 显示负载 6.8(4 核机器)。top 展开后看到 us 占 85%,单个 PHP-FPM 进程吃满一个核心——最后定位是一个定时任务恰好在这个时间点执行了无索引的数据库查询。如果没有先看负载分布,很容易误判成带宽(网络传输能力)不足而白忙一场。
在 top 里锁定嫌疑进程:排序、字段与操作
确认 CPU 确实异常后,就在 top 界面里锁定具体进程。top 默认按 CPU 占用降序排列,但误触排序后可能变成按内存排列,此时按大写 P(Shift+p)即可恢复按 CPU 排序,按 M 则切换到内存排序。排在第一行的进程就是头号嫌疑对象,但要连续观察 30 秒以上:有些进程是间歇性脉冲占用(比如日志切割),常驻第一行 1-2 秒就下去的进程未必是元凶,长期钉在 90% 以上的才是真问题。
top 的几个字段需要能读懂:%CPU 是单核归一化后的占用率,一个进程显示 200% 意味着吃满两个核心;TIME+ 是进程启动以来累计的 CPU 时间,如果这个数字在飞速增长而业务量并没有上涨,基本可以判定异常;RES 是实际占用的物理内存,帮助判断这个进程是否还伴随内存泄漏。按 c 可以显示进程的完整启动命令,这是判断进程身份最关键的一步——只看进程名 php-fpm 没法区分正常业务和异常请求,展开后的完整命令行往往直接暴露问题脚本路径。
锁定目标进程后,在 top 界面按 k 可以直接发送信号终止它,输入进程号回车即可。但这里要克制:对未知进程先不要急着杀。曾有网友在 top 里看到一个名字随机的进程占了 90%,直接 kill -9,结果十几分钟后进程又回来了——那是一台被植入挖矿木马的服务器,杀掉进程只会触发守护脚本重新拉起。正确的做法是先按 c 记下完整命令路径,再去查它的启动来源,这部分我们放到后文讲。
用 ps 追查进程身份:命令、路径与启动来源
top 看到的是”此刻”,ps 提供的是更完整的档案。进程占用高时,先复制它的 PID(进程号),然后执行:
ps -fp <PID>
输出里的关键信息有四项:UID 告诉你进程属于哪个用户——业务进程跑在 www 或 www-data 下是正常的,如果出现在 nobody、daemon 或陌生用户下就要警惕;CMD 显示完整命令行,配合 ps -fp 的 -f 参数才能看到,这是区分”同名进程”的唯一依据;STIME 是启动时间,启动几分钟却占用异常的进程,大概率对应一次刚发生的入侵或刚上线的坏代码;PPID 是父进程号,异常进程的父进程往往指向可疑的守护者。
父进程是追查链的关键一环。用 ps -fp <PPID> 继续向上追,挖矿木马的典型特征是一条陌生的父进程链,最终落在某个 crontab 定时任务或者被篡改的服务文件上。顺手执行 crontab -l 查看当前用户的定时任务,再用 grep -r "关键词" /etc/cron* /var/spool/cron 扫一遍系统级任务目录,很多入侵者就是靠一条每分钟执行一次的定时任务维持存活的。如果需要批量对比所有进程的 CPU 排名(比如要截图留证或写入工单),ps 的静态快照比 top 的动态界面更合适:
ps -eo pid,ppid,user,%cpu,%mem,stime,cmd --sort=-%cpu | head -15
这条命令列出 CPU 占用前 15 的进程并附带父进程、用户和启动时间,输出结果是纯文本,方便粘贴到故障报告里。反过来,如果追查发现消耗 CPU 的是正常业务(比如促销期间的搜索请求激增),那就不是”杀进程”能解决的,而是容量问题——要么优化代码与数据库查询,要么升级到更大的配置,可以参考服务器选购指南评估升级路径。

常见高 CPU 场景与对应处理
定位到进程之后,怎么处置取决于它是谁。结合日常工单里最频繁出现的几类场景,可以按下面的路径处理。
- 业务进程(php-fpm、MySQL、Nginx worker):先看请求日志确认是真实流量暴涨还是慢查询拖慢了 worker。PHP 站点常见于 WordPress 插件死循环,MySQL 常见于无索引查询,处理方向是修代码、加索引、调缓存,而不是简单重启。WordPress 站可以参考WordPress 数据库优化指南系统性排查慢查询。
- 定时任务失控(crond 拉起的脚本):特征是占用高但每几分钟会消失又出现。检查
crontab -l里的备份、同步类脚本,常见问题是脚本没有加执行锁,上一轮没跑完下一轮又启动,进程越积越多。加flock锁或者拉长执行间隔即可解决。 - 挖矿木马(名字随机、路径在 /tmp 或 /dev/shm):不要只杀进程,先
ps -fp追父进程、清定时任务、查公钥文件/root/.ssh/authorized_keys是否被写入陌生条目,处理完这些再杀进程才不会复活。清理完成后建议按服务器安全加固清单做一轮全面检查。 - 系统进程(kswapd0、kworker):kswapd0 占用高说明内存在疯狂交换,罪魁是内存不足而非 CPU 本身,先看 top 里
%MEM排名找出内存大户。kworker 高则常与磁盘 I/O 或网卡驱动相关,需要结合iostat判断。
处置完毕后,用 top 再观察 15 分钟,负载回落到核心数以内、且没有新进程重新爬到榜首,才算真正解决。若占用是业务量上涨带来的长期性升高,就该考虑资源扩容了——对于持续增长的站点,独立服务器提供独享的 CPU 与内存,比反复调优共享环境更省心。

排查习惯与总结建议
高 CPU 排查本身不难,难的是出事时冷静按顺序来:先 uptime 确认负载,再 top 锁进程、读懂 %CPU 与 TIME+,然后用 ps 追身份和父进程,最后按进程类型对症处置。跳过中间步骤直接重启或杀进程,是大多数问题反复复现的原因。
我们的建议是:在常用服务器上把 uptime、top、ps -fp 这三步演练一遍,熟悉各自的输出含义;同时在业务低峰期检查一遍 crontab -l,确认每条定时任务你都认识——这一项就能挡住大多数挖矿木马的复活路径。如果你需要一台权限完整、配置明确的实验或生产环境,支持 root 权限的 VPS 主机适合作为练习机,Hostease 的这类方案预装了完整的 top、ps 工具链,可以考虑开通一台把本文命令全部跑熟。遇到单机资源持续不足的情况,再结合业务增长节奏评估独立服务器方案,把排查精力留给真正需要的时刻。