Linux 服务器 CPU 占用 100% 怎么排查?先找进程还是先重启
Linux CPU 100% 需要先确认是谁在消耗 CPU,再判断是业务高峰、程序异常、攻击请求还是异常进程。本文按现场保留、进程定位和日志分析展开。
Linux 服务器 CPU 占用 100% 时,最忌讳的是还没看现场就重启。重启可能让网站暂时恢复,但异常进程、攻击请求、慢查询和任务堆积的线索也会一起消失。正确做法是先定位“谁占用 CPU”,再判断“为什么占用”。
先保留现场,再决定是否重启
如果业务还没有完全不可用,先执行:
top
按 `P` 按 CPU 排序,记录占用最高的进程名、PID、运行用户、CPU 占比和持续时间。再导出固定列表:
ps -eo pid,ppid,user,cmd,%cpu,%mem --sort=-%cpu | head -n 20
`cmd` 比进程名更重要,它能看到启动路径和参数。陌生路径、隐藏目录、`/tmp`、`/var/tmp`、网站上传目录里的可执行文件都需要警惕。
按进程类型判断方向
| 高占用进程 | 常见方向 | 继续看什么 |
|---|---|---|
| `php-fpm` | 慢接口、插件、程序死循环、访问高峰 | Nginx 日志、PHP 错误日志 |
| `mysqld` | 慢查询、连接数过多、索引问题 | 慢查询日志、当前连接 |
| `java` / `node` | 应用线程、队列、内存压力 | 应用日志、进程参数 |
| `nginx` | 大量请求、静态文件压力、异常访问 | access.log |
| 陌生进程 | 入侵、挖矿、异常脚本 | 进程路径、计划任务、登录日志 |
查看进程来源
ls -l /proc/进程PID/exe
这能看到进程实际可执行文件。还可以看启动目录:
pwdx 进程PID
如果进程来自临时目录或上传目录,不要只 kill 掉就结束,应继续查它如何被启动。可以继续检查计划任务:
crontab -l
ls -la /etc/cron*
如果是 Web 请求打满
查看 Nginx 访问日志:
tail -n 200 /var/log/nginx/access.log
如果短时间大量请求集中在同一接口、同一 IP、同一 User-Agent,可能是爬虫、刷接口或 CC 攻击。如果请求分布正常但 PHP 或数据库高,可能是程序性能问题。
还可以按 IP 粗略统计:
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head
这不是最终结论,但能帮助判断是否有明显来源集中。
如果是数据库打满 CPU
MySQL 高 CPU 不建议直接 kill。应先看当前连接和慢查询。可以通过 MySQL 客户端查看进程列表,或开启慢查询日志。数据库 CPU 高常见于缺索引、慢 SQL、连接数暴涨、定时任务集中执行。
CPU 高和 Load 高不是一回事
在 `top` 里关注 `wa`。如果 `wa` 高,CPU 可能在等磁盘 IO,而不是计算真的满了。此时只升级 CPU 不一定有效,可能要查磁盘、数据库或日志写入。
错误操作提醒
不要直接 `kill -9` MySQL、游戏服主进程或正在写数据的服务。不要不记录现场就重启。必须恢复业务时,可以优先重启单个异常服务,而不是整机重启。
用户可以定位高占用进程、访问日志和最近变更。如果怀疑攻击、挖矿、宿主机 CPU steal 异常、网络清洗或外发流量异常,需要服务商协助确认底层资源和安全事件。