1. 项目概述
当Linux服务器的CPU使用率突然飙升时,作为系统管理员或运维工程师,我们需要一套完整的应急处理流程。这不仅包括快速定位问题的技术手段,更需要从根本上预防类似问题的再次发生。本文将分享我在生产环境中处理CPU飙高问题的实战经验,涵盖从问题发现到根治的全套解决方案。
2. 快速定位CPU问题
2.1 实时监控工具使用
当收到CPU告警时,我首先会使用top命令进行初步检查:
code复制top -c
这个命令能实时显示CPU占用最高的进程。关键要看%CPU列和COMMAND列,-c参数可以显示完整命令路径。
更详细的监控可以使用htop工具(需要安装):
code复制htop
htop的优势在于彩色显示和更直观的进程树视图,支持鼠标操作和进程筛选。
2.2 进程级分析
对于可疑进程,我会使用pidstat进行更细致的分析:
code复制pidstat -u -p [PID] 1 5
这个命令会每1秒采样一次,共采样5次,显示指定进程的CPU使用详情。
2.3 线程级排查
有时候问题出在单个线程上,这时需要:
code复制top -H -p [PID]
或者使用更强大的perf工具:
code复制perf top -p [PID]
3. 深入分析CPU使用情况
3.1 系统负载检查
查看系统负载平均值:
code复制uptime
cat /proc/loadavg
负载值超过CPU核心数就表示系统过载。
3.2 CPU使用明细
使用mpstat查看每个CPU核心的使用情况:
code复制mpstat -P ALL 1
这个命令特别适合多核CPU的环境,可以发现是否有个别核心过载。
3.3 中断分析
高中断也可能导致CPU飙高:
code复制cat /proc/interrupts
watch -n 1 "cat /proc/interrupts | sort -nr"
4. 常见问题类型及解决方案
4.1 Java应用CPU过高
对于Java应用,我常用的排查步骤:
- 使用top找到Java进程PID
- 获取线程栈:
code复制jstack [PID] > thread_dump.log
- 使用jstat检查GC情况:
code复制jstat -gcutil [PID] 1000 5
4.2 数据库查询导致CPU高
MySQL数据库CPU高时:
code复制show processlist;
explain [问题SQL];
需要特别关注State为"Sending data"或"Sorting result"的查询。
4.3 系统进程占用高CPU
如果是系统进程如kswapd0占用高CPU,可能是内存不足导致频繁交换:
code复制free -h
vmstat 1 5
5. 根治与预防措施
5.1 应用层优化
- 代码审查:检查是否有死循环、低效算法
- 连接池配置:确保数据库连接池大小合理
- 缓存策略:合理使用缓存减少计算量
5.2 系统层调优
内核参数调整示例:
code复制# 减少swap使用倾向
vm.swappiness = 10
# 文件描述符限制
fs.file-max = 65535
5.3 监控体系建设
建议部署的监控项:
- CPU使用率(整体和单核)
- 系统负载
- 关键进程资源占用
- JVM内存和GC情况(对Java应用)
使用Prometheus+Grafana可以实现完善的监控体系。
6. 实战案例分享
最近处理的一个案例:某电商网站在大促时CPU持续100%。通过perf分析发现是商品搜索接口的模糊查询导致。解决方案:
- 紧急方案:增加查询缓存时间
- 中期方案:优化SQL索引
- 长期方案:引入Elasticsearch
7. 应急工具箱
我维护的应急工具脚本包括:
- 快速抓取系统状态:cpu_check.sh
- Java线程分析:java_thread_analyze.sh
- 历史CPU数据对比:cpu_history_compare.py
这些脚本都配置了alias,可以快速调用。
8. 经验总结
处理CPU问题的几个原则:
- 先止血再治病:快速降低CPU使用恢复服务
- 保留现场证据:在重启前收集足够日志
- 根因分析:找到真正原因而非表象
- 预防为主:建立完善的监控预警机制
每次处理完CPU问题后,我都会更新这个应急手册,补充新的案例和经验。这个持续改进的过程让我们的系统越来越稳定。
