服务器CPU突然飙高,先别急着重启,正确的做法是登录服务器快速定位高负载进程,再针对性处理,绝大多数情况都能在几分钟内解决。
服务器CPU飙高的常见原因有哪些
CPU占用率突然拉满,背后通常藏着几类问题,搞清楚这些诱因,排查时才能有的放矢,不至于像无头苍蝇一样乱试。
应用程序代码出现死循环或逻辑缺陷
这是最常见的触发点,某个应用上线了新版本,或者定时任务被异常触发,代码在特定数据输入下陷入死循环,表现特征比较明显:CPU单核或多核持续100%占用,top命令下能看到某个进程长期霸榜,这种情况常见于Java、PHP、Python写的业务服务。
数据库慢查询瞬间暴涨
当数据库里的SQL语句没有走索引,或者数据量增长后原有的查询计划失效,一次全表扫描会吃掉大量CPU资源,如果此时并发请求恰好变多,CPU就会被拖垮,典型的场景是:CPU飙高的同时,数据库连接数也迅速上升,慢查询日志里堆满了未优化的SQL。
突发流量或恶意攻击
活动大促、热点事件带来的访问量激增,或者服务器被DDoS、CC攻击,大量请求涌入会直接打满CPU,这类情况的特征是网络连接数异常增多,尤其是SYN_RECV、ESTABLISHED状态的连接远高于平时水平。
系统自身软件或内核异常
操作系统层面的问题也不容忽视,Linux内核出现死锁,或者某些驱动模块存在缺陷,还有常见的OVH、KVM等虚拟化环境下CPU Steal过高,都会让服务器无端消耗CPU,这类问题在dmesg日志中通常能找到蛛丝马迹。
挖矿木马或病毒入侵
服务器被植入挖矿程序,利用CPU资源计算加密货币,多数情况下,这类进程会伪装成系统进程名或者随机字符串,CPU占用率几乎恒定在较高水平,排查时容易识别,但清理起来需要格外小心。
服务器cpu占用过高怎么解决:五分钟定位法
按部就班来,先从系统层面快速锁定异常来源,这也是业内通用的第一轮排查手段,整个过程大概需要五分钟,建议打开终端直接操作。
第一步:用top命令找到CPU大户
登录服务器后,第一时间执行top命令,按一下大写字母P,让进程按照CPU使用率排序,重点看 %CPU列 排在最前面的几个进程。
- 如果某个业务进程CPU占用接近100%,多数是代码逻辑问题。
- 如果进程名很陌生,是一串乱码或者像
kworker、systemd的非预期进程,警惕挖矿木马。 - 如果整体CPU使用率都很高,但每个进程都不算突出,考虑流量攻击或CPU Steal。
第二步:查看线程级消耗
top只显示进程,有时候问题藏在某个进程的特定线程里,用top -Hp 进程PID查看该进程下所有线程的CPU消耗,记下异常线程的TID,这个步骤能帮助开发人员精准定位到代码的具体行号。
第三步:检查负载与核心数关系
执行uptime查看系统负载,业内专家指出,当负载值持续高于CPU核心数的四倍时,系统已经处于过载状态,这时候不光要处理CPU,还得考虑扩容或限流。
- 负载 = 核心数,属于正常边界。
- 负载 = 核心数2倍,感知明显卡顿。
- 负载 = 核心数4倍甚至更高,系统基本不可用。
第四步:追踪进程启动路径
对于可疑进程,用ls -l /proc/进程PID/exe查看它的实际执行文件路径,再用cat /proc/进程PID/cmdline查看启动参数,这一步能快速区分是正常业务还是入侵程序。
| 检查项 | 正常业务进程 | 可疑进程 |
|---|---|---|
| 启动路径 | 通常在应用部署目录 | 经常在/tmp、/var/tmp |
| 启动用户 | 专属应用账号 | root或www-data |
| 网络连接 | 监听固定业务端口 | 连接境外陌生IP |
服务器CPU飙高排查后的针对性处理方案
定位到原因后,处理手段各不相同,以下方案覆盖绝大多数线上场景,按实际情况选择即可。
应用代码问题的应急处理
先止血,后根治。 如果确认是某个应用导致CPU满负荷,而且一时半会儿改不了代码,直接终止该进程,让服务快速恢复,记录下当前进程的PID,然后执行kill -9 PID强制结束。
服务恢复后,开发团队需要复盘代码,重点检查最近一次发版内容,尤其是循环边界条件、正则表达式回溯、JSON解析逻辑,常见的一个坑是,正则表达式在匹配长字符串时出现灾难性回溯,CPU瞬间被拉满,这类问题在代码评审时不容易发现,通常需要压测才能暴露。
数据库慢查询的治理路径
先处理数据库侧,登录数据库,执行SHOW PROCESSLIST,找到State为Sending data或者Sorting result的长事务。优先杀掉执行时间最长的几个会话,给数据库降压。
然后针对这些慢SQL,用EXPLAIN查看执行计划,缺索引的补索引,多表关联的优化关联顺序,大分页的改写成分页查询,行业共识认为,超过80%的数据库CPU问题都能通过加索引和改写SQL解决,剩下的再考虑从库分流或者升级硬件。
流量攻击的应对策略
先在防火墙层面快速封禁可疑IP,用netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n统计连接数排名前十的IP,确认无误后执行封禁。
- 1分钟内临时封禁:
iptables -A INPUT -s IP地址 -j DROP - 永久封禁:把规则写入防火墙配置文件
如果带宽消耗严重,单靠服务器自身防火墙可能支撑不住,必须联系机房或云服务商开启流量清洗,平时建议提前配置好云安全组策略,只对外开放必要的端口,缩小攻击面。
挖矿木马的清理流程
清理挖矿病毒,步骤比想象的繁琐,按照下面顺序依次执行,缺一不可。
- 断开服务器外网连接,防止木马继续与远端控制端通信。
- 查看
crontab -l和/etc/crontab,删除异常的定时任务。 - 使用
lsof -p PID查看木马进程打开的文件,清理掉源文件。 - 检查
/root/.ssh/authorized_keys,删除不明公钥,防止黑客再次登录。
全盘执行一次clamav杀毒扫描,确认没有残留的恶意文件,如果服务器被深入入侵,建议直接备份数据后重装系统,这是最稳妥的做法。
服务器CPU持续偏高的长期优化方案
短期应急解决不了所有问题,要让服务器稳定运行,还得从容量规划与配置层面着手,这里重点分析cpu占用高时需要关注的几个维度。
合理配置监控告警阈值
人不可能24小时盯着终端窗口,但监控系统可以,建议把CPU使用率的告警阈值设置在75%到80%之间,持续五分钟以上即触发告警,这样既能过滤掉瞬时高峰的误报,又能保证在CPU被打满前收到提醒。
同时在监控大盘上,把CPU使用率和应用QPS、响应时间放在同一张图里观察,如果CPU升高伴随着响应时间同步上涨,说明是真实负载增长;如果CPU升高但QPS没变,大概率是代码出了性能问题。
应用层面的限流与降级
线上应用必须配置限流规则,防止突发流量直接打穿后端服务,常见的限流策略有三种:
- 基于QPS的限流:单机每秒最多处理多少请求,超出部分直接返回友好提示。
- 基于并发数的限流:同一时刻最多允许多少线程处理业务,防止线程池被占满。
- 基于CPU负载的限流:系统负载超过阈值时自动触发降级,关闭非核心功能。
架构层面的横向扩容
单台服务器的CPU资源总归有限,当业务处于上升期,扩容是不可避免的选择。核心业务至少部署两台服务器做负载均衡,一台故障时另一台接管流量,对用户体验几乎无感。
数据库层面同样需要拆分,读多写少的场景,用一主多从架构,把读请求分发到从库;写入量大的场景,按业务维度做分库分表,减轻单库压力。
服务器cpu占用过高怎么排查的常见问答
服务器CPU很高但load average不高,是什么情况?
可能单核CPU资源饱和,但整体负载尚未传递到系统层面,重点检查进程是否被绑定在某个固定CPU核心上,使用taskset查看进程的CPU亲和性设置,另外短进程频繁创建销毁也会造成这种现象,CPU忙于切换上下文但负载指标波动不大。
为什么重启服务器后CPU还是高?
重启只能清除内存中的临时进程和缓存垃圾,但如果问题根源是开机自启动脚本携带了挖矿程序,或者应用代码本身存在缺陷,重启之后这些程序会再次加载,CPU自然又会飙高,重启完成后需要立即检查系统启动项和进程列表,确认异常服务是否再次拉起。
云服务器CPU突然飙高,怎么判断是自身问题还是宿主机超卖?
登录云服务商控制台查看监控数据中的CPU Steal指标,如果CPU使用率核心指数不高,但CPU Steal长时间超过10%,说明宿主机资源竞争激烈,这是服务商层面的问题,最直接的办法是升级到独享型实例,或者在工单系统里反馈让技术支持协助迁移到负载较低的物理机。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/783207.html


