服务器CPU飙高可谓运维工单里最让人头疼的问题之一。用户反馈慢得像爬虫,控制台敲命令都卡顿,严重时SSH连接都无法正常建立。定位CPU问题不能靠猜测,必须有一套从粗到精的排查方法论。
确认CPU异常并初步分类
首先用top命令看实时CPU使用率,重点关注us、sy、wa、id四个指标的百分比。us很高说明用户态应用在大量消耗CPU,sy很高意味着系统调用或内核线程繁忙,wa高则提示磁盘I/O可能是间接原因。同时查看load average的三个数值,如果十五分钟负载也远高于CPU逻辑核心数,说明问题已经存在了一段时间。使用uptime可以快速确认运行时长和平均负载,再结合vmstat看上下文切换频率和运行队列长度。上下文切换每秒超过数万次时,即使CPU使用率不高,大量线程争抢也会导致响应变慢。
定位占用CPU的进程和线程
在top界面按P键按CPU使用率排序,记下异常进程的PID。再用top -H -p PID查看该进程内部哪些线程消耗最多CPU。如果是Java应用,使用jstack导出线程快照,结合线程ID在堆栈中搜索对应信息,判断是GC频繁、锁竞争还是业务代码死循环。如果是PHP应用,在php-fpm慢日志中定位执行时间过长的脚本,排查SQL查询是否没走索引。如果是MySQL进程,登录数据库执行show full processlist,看有没有大量查询处于Sending data状态,这种通常是用错了JOIN或缺失索引导致全表扫描。如果是Nginx进程,检查是否有大量静态请求涌入,考虑加缓存层分担压力。
深入分析根因并制定方案
定位到具体瓶颈后需要对症下药。业务代码死循环直接修代码并重启服务。SQL慢查询分析执行计划后加复合索引或改写为更高效的查询模式。如果是突发的流量峰值导致CPU飙升,考虑临时扩容或者在前端启用限流降级策略。硬件层面散热不良导致CPU降频也是常见原因,使用sensors命令查看温度,长期超过八十度会影响CPU性能发挥。注意区分持续型飙高和偶发型毛刺,前者通常有明确根因,后者可能和定时任务周期性执行有关。排查过程中保留完整的性能快照和日志,以便后续回溯。
建立长效监控与预防机制
部署CPU使用率的监控告警,建议阈值设在百分之八十五持续五分钟。趋势分析比单一阈值更有价值,通过Grafana等工具查看CPU使用的周同比和环比曲线。定期做代码审查关注循环、递归和频繁IO操作的代码段。核心业务建议每季度做一次压力测试,摸清服务器吞吐上限。CPU问题虽然紧急,但只要手里有一套成熟的排查体系,多数情况下都能在三十分钟内搞定。