服务器CPU使用率飙到90%以上,第一步不是加配置,而是先用top看清us、sy、wa、st四个值谁在涨先分清是用户态忙、内核态忙、IO卡还是被宿主机抢了资源,再决定是改代码、调参数还是换机型。 大多数情况下,盲目升配只是把问题延后半小时。
先判断“真高”还是“假高”
监控面板上那条红线经常骗人,CPU使用率有多种算法,top顶部显示的%Cpu(s)是瞬时值,采集工具算的可能是15秒或1分钟均值,两者能差出一倍,动手前先做三件事:
- 用
uptime看1分钟、5分钟、15分钟负载,如果三个数字依次递减,说明只是瞬时尖峰,不必处理。 - 用
vmstat 1盯几轮,重点看r列(运行队列)和cs列(上下文切换)。r长期大于CPU核数,才是真排队。 - 用
mpstat -P ALL 1看是否单核打满、其他核躺平,单核100%多半是单线程程序或锁竞争,多核一起高才是整体负载。
如果wa(IO等待)占比大,而us并不高,那不是CPU的锅,去查磁盘和网络。 很多工单最后发现是日志盘写满或者磁盘打滑,CPU只是在陪跑。
云服务器CPU使用率过高和物理机有什么不一样
这是排查方向的分水岭,云主机多了一个st(steal time)指标,它表示物理宿主机把CPU时间分给了别的虚拟机。st持续超过5%,说明你这台实例在跟邻居抢资源,此时优化代码毫无意义,正确做法是提工单要求迁移宿主机,或者换成独享型、计算型实例。
物理机则要看是否被其他进程干扰,top里按P排序就能看到排名前列的“元凶”,另外云盘和本地盘的IO模型不同,云上wa高有时是云盘IOPS配额被打满,这种情况升级CPU规格没有任何效果,要单独提IOPS。
服务器CPU使用率过高怎么排查:四步定位法
业内专家指出,CPU问题的排查顺序应该是“整体→进程→线程→代码”,跳步容易走回头路。
第一步,锁定进程。 执行:
ps -eo pid,ppid,%cpu,%mem,etime,cmd --sort=-%cpu | head -20
注意etime列,一个刚启动就吃掉80%CPU的进程,和一个稳定运行30天的进程突然吃满,性质完全不同,前者多半是死循环或初始化计算,后者通常是流量变化或数据量增长。
第二步,看进程内部。 用pidstat -u -p <PID> 1 5看它是否周期性尖刺;用strace -c -p <PID>统计系统调用耗时,如果大量时间花在read、write、futex上,方向就转向了IO或锁。
第三步,抓线程栈。 Java应用用top -Hp <PID>找到最耗CPU的线程ID,转成十六进制后jstack <PID> | grep -A 30 <nid>定位代码行,PHP、Python应用用py-spy top --pid <PID>或pstack直接看调用栈。连续抓三次、间隔5秒,三次都出现在同一个函数的线程,基本可以认定是热点。
第四步,验证而非猜测。 把嫌疑代码在预发环境复现,用perf top -p <PID>看函数级火焰数据,确认后再改。
几个高频场景的对症下药
- MySQL把CPU吃满:先开慢查询日志,
long_query_time调到1秒,用pt-query-digest分析Top SQL,缺索引的补索引,Using filesort和Using temporary多的改写法。SHOW PROCESSLIST里出现大量Sending data状态,往往是全表扫描。 - Nginx/Apache扛不住:看
access.log里是不是有单IP高频请求,用awk '{print $1}' access.log | sort | uniq -c | sort -rn | head十秒出结果,有就上限流,没有就考虑开缓存或加机器。 - 定时任务扎堆:
crontab -l看一眼,凌晨整点多个备份、统计任务同时跑,CPU瞬间冲顶是常事,错开执行时间是最便宜的一招。 - PHP-FPM进程数配太多:
pm.max_children按“可用内存÷单进程内存”算,配大了不仅吃CPU,还会触发频繁进程切换,sy会明显升高。
网站访问慢、CPU占用高,到底是流量问题还是代码问题
这两个原因的处理成本差十倍,必须分清,看两个比值:QPS增长比例与CPU增长比例是否同步,如果QPS翻了一倍、CPU也翻了近一倍,是流量型,扩容或加缓存就能解决;如果QPS没变、CPU却涨了,大概率是数据量变大导致查询变慢,或者有慢SQL、内存泄漏在拖后腿。
再补一个判断依据:看load average与CPU使用率的比值,负载高但CPU使用率不高,通常是IO阻塞或锁等待;两者一起高,才是真在算东西,行业共识认为,超过八成的“网站慢”投诉最终落在数据库和外部接口调用上,而不是Web服务器本身。
应急止血与长期治理
线上已经炸了的时候,别急着优化代码,先保住可用性:
- 用
cpulimit -p <PID> -l 70给异常进程限速,防止拖垮整机。 - 在Nginx层面对高频接口做限流,
limit_req_zone配好,先挡住异常流量。 - 把非核心的定时任务、日志切割临时停掉,让出CPU。
- 如果是单点故障,先把流量切到备机,再慢慢分析。
长期看,三件事最有效:加监控告警(CPU持续5分钟超过80%就通知)、加缓存(Redis挡掉大部分重复查询)、做容量评估(按业务峰值预留30%余量),据工信部相关运行监测数据,国内中小站点因配置不当导致的资源浪费现象相当普遍,很多实例常年CPU不到10%,却在高峰期被瞬时流量打穿。
解决服务器CPU使用率过高要花多少钱
这是老板最关心的问题,也是很多人容易走偏的地方,先说结论:大部分CPU问题不需要花钱,需要花钱的时候,优先买“更合适的配置”而不是“更大的配置”。
| 处理方式 | 成本量级 | 适用场景 |
|---|---|---|
| 改代码、加索引、调参数 | 零硬件成本,只花人力 | 慢SQL、死循环、配置不合理 |
| 加缓存层(Redis) | 每月几十到几百元 | 读多写少、重复查询多 |
| 升配CPU/内存 | 每月几百到上千元 | 流量确实增长、计算密集型业务 |
| 换成独享型/计算型实例 | 比共享型贵一档 | st高、资源被邻居抢占 |
| 加机器做负载均衡 | 翻倍成本 | 单机已到瓶颈、需要高可用 |
按量计费的实例适合临时扛峰值,包年包月适合稳定业务。先花一天排查,再决定掏不掏钱,这个顺序几乎不会错。
关于服务器CPU使用率过高的常见问答
服务器CPU使用率长期在70%左右,需要处理吗
看趋势不看单点,如果业务高峰期70%、平时30%,属于正常水位,留有余量即可,如果连续一周平稳爬升且不回落,说明有资源在缓慢泄漏或数据量在增长,此时要排查,不必等它到90%再动手。
加了CPU核数为什么使用率反而更高了
常见于两种情况:一是程序是多进程模型,核数变多后进程数同步增加,锁竞争和上下文切换变多,sy升高;二是虚拟机跨NUMA节点调度,内存访问变慢,CPU空转等待,先确认程序的并发模型是否随核数线性扩展,再决定要不要回退。
云服务器CPU使用率过高,重启能解决吗
重启只能清掉内存泄漏和僵死进程带来的临时问题,治标不治本,重启后如果几小时内使用率再次爬升,说明根因还在,必须回到进程和线程层面定位,重启前记下top和ps的输出,那是唯一的现场证据,重启后就没了。
CPU使用率是个结果指标,不是原因。把它当成报警器而不是诊断书,顺着us、sy、wa、st四条线索往下走,绝大多数问题都能在半小时内锁定方向。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/790398.html


