生产环境收到 CPU 或 Load Average 告警时,最忌讳直接重启。负载升高不一定等于 CPU 使用率高:大量不可中断 I/O、锁等待和僵死任务同样会推高负载。正确做法是先确认影响,再保存现场,最后按 CPU、内存、I/O、进程和外部依赖逐层定位。
一、先判断业务影响
接口延迟和错误率是否升高;
是否只有一台机器异常,还是整个集群同时异常;
告警前是否发生发布、批处理、流量增长或配置变更;
是否达到需要切流、扩容或降级的程度。
不要只看一个瞬时数值。先执行:
uptime
top
vmstat 1 10uptime 查看 1、5、15 分钟负载趋势。负载应结合 CPU 核数判断,但“超过核数”只是线索,不是故障结论。vmstat 中 r 长期大于 CPU 核数通常表示运行队列拥堵;b 较高表示大量任务处于不可中断等待。
二、判断是 CPU 还是 I/O
mpstat -P ALL 1 10
iostat -x 1 10%usr高:应用计算、压缩、加密或死循环;%sys高:系统调用、网络包、驱动或内核开销;%iowait高:磁盘慢,但还要结合磁盘利用率和延迟;%steal高:虚拟机被宿主机争抢 CPU;await、队列长度和%util持续高:重点检查存储。
三、定位异常进程和线程
ps -eo pid,ppid,user,stat,%cpu,%mem,etime,cmd --sort=-%cpu | head -30
pidstat -u -r -d -w 1 10
top -H -p <PID>确认是单个进程、多个实例还是内核线程造成。Java 进程应把高 CPU 线程 ID 转换为十六进制,再与线程栈对应;数据库进程则需要继续检查慢 SQL、锁等待和后台任务。
printf '%x\n' <TID>
jstack <PID> > /tmp/jstack.$(date +%s).txt四、检查内存、换页和系统压力
free -h
sar -r 1 10
sar -W 1 10
cat /proc/pressure/{cpu,memory,io}频繁换页会让系统表现为负载高、响应慢。si/so 持续不为零时,应检查内存不足、进程泄漏或容器内存限制。PSI 可以帮助判断 CPU、内存或 I/O 是否真正造成任务阻塞。
五、检查 D 状态与阻塞任务
ps -eo state,pid,ppid,wchan:32,cmd | awk '$1=="D"'
cat /proc/<PID>/stack大量 D 状态进程通常与磁盘、NFS、块设备或内核驱动有关。此时杀进程可能无效,应先恢复底层依赖。不要把“kill -9 无效”误判为权限问题。
六、紧急止血
根据影响程度选择:摘除异常节点、暂停批处理、限制并发、扩容实例、降低日志量、回滚发布或启用业务降级。止血前尽量保存 top、vmstat、pidstat、iostat、线程栈和系统日志,避免重启后证据消失。
七、长期治理
建立 CPU、运行队列、PSI、磁盘延迟和业务延迟联合告警;
对批处理设置资源限制和错峰策略;
发布前进行容量评估与压测;
为高风险服务准备限流、降级、切流和自动扩容;
故障后记录时间线、根因、止血动作和防复发措施。
总结
负载升高只是结果。排查的核心是区分运行队列和不可中断等待,再定位到具体进程、线程、磁盘或外部依赖。先保存现场、再止血、最后治理,才能把一次告警变成可复用的运维经验。