
Linux服务器突然变慢时,uptime 或 top 中不断升高的 Load Average 往往最先引起注意。很多人看到负载超过CPU核心数,就立即认定CPU配置不足,随后重启服务器或直接扩容。
但系统负载并不等于CPU使用率。Linux负载统计既包括正在运行或等待CPU的任务,也包括处于不可中断睡眠状态、通常正在等待磁盘或网络存储I/O的任务。因此,CPU没有跑满时,Load Average仍然可能很高。
正确的排查思路是:先判断负载趋势和服务器CPU数量,再区分任务是在等待CPU、等待I/O,还是被内存回收、网络存储、锁竞争或异常进程拖住,最后定位具体进程并处理根因。
本文提供一套适用于常见Linux服务器的负载排查流程。命令输出会因发行版、内核和工具版本不同而略有差异,生产环境执行停止服务、终止进程或调整参数前,应先确认业务影响。
一、Load Average究竟表示什么
执行:
uptime
输出末尾通常包含三个负载值,分别表示最近1分钟、5分钟和15分钟的平均负载。
也可以直接查看:
cat /proc/loadavg
示例:
2.18 1.76 1.31 3/642 28194
前三个数字仍然是1分钟、5分钟和15分钟平均负载。3/642 中,前一个数字表示当前可运行的调度实体数量,后一个数字表示系统中的调度实体总数;最后一个数字是最近创建进程的PID。
Load Average可以理解为一段时间内处于以下状态的任务数量:
- 正在CPU上运行。
- 已经可以运行,但正在等待CPU调度。
- 处于不可中断睡眠状态,常见于等待磁盘、云盘、NFS或其他内核I/O操作。
因此,负载为8并不表示CPU使用率一定是800%,也不代表一定需要增加8个CPU。它反映的是系统中有多少任务正在运行或被关键资源阻塞。
二、负载多高才算异常
先查看逻辑CPU数量:
nproc
也可以查看更完整的处理器信息:
lscpu
假设服务器有4个逻辑CPU:
- 负载长期低于4:通常说明CPU运行队列没有持续积压,但仍需结合响应时间判断。
- 负载长期接近4:CPU资源可能比较繁忙,但不一定已经影响业务。
- 负载持续明显高于4:可能存在任务排队,也可能有大量任务处于不可中断睡眠。
- 负载短暂超过4:可能只是定时任务、备份、流量峰值或批处理,不应仅凭一次峰值处理。
“负载不能超过CPU核心数”只是便于理解的经验,不是绝对告警线。不同业务对延迟的容忍度不同。计算任务可以在高负载下稳定运行,而对响应时间敏感的网站即使负载不高,也可能因单线程瓶颈或存储延迟出现卡顿。
更可靠的判断需要同时观察:
- 1分钟、5分钟和15分钟负载趋势。
- CPU使用率和每个核心的繁忙程度。
- 运行队列长度。
- I/O等待和不可中断任务数量。
- 内存、Swap和资源压力。
- 网站响应时间、错误率与数据库延迟。
三、从三个负载值判断变化趋势
三个负载值不仅表示平均值,还能帮助判断问题是在加重还是恢复。
1. 1分钟值高于5分钟和15分钟
例如:
12.20 7.10 3.40
说明负载近期快速上升。需要立即检查新出现的流量、任务、进程和I/O活动。
2. 三个值都很高且接近
例如:
9.80 9.60 9.20
说明高负载已经持续一段时间,通常不是瞬时峰值。
3. 1分钟值低于5分钟和15分钟
例如:
3.10 6.40 8.70
说明压力正在下降。此时仍应保留现场信息,确认是什么任务结束了,以及问题是否会再次出现。
Load Average是平均指标,会有滞后。进程停止后,15分钟负载不会立即恢复正常,所以不能把负载值尚未归零误认为处理无效。
四、第一步:判断是CPU排队还是I/O阻塞
执行:
top
重点观察CPU状态:
| 指标 | 常见含义 | 可能方向 |
|---|---|---|
| us | 用户态程序消耗CPU | Web应用、数据库查询、脚本、计算任务 |
| sy | 内核态消耗CPU | 系统调用、网络包处理、驱动、内核活动 |
| id | CPU空闲比例 | 持续很低通常表示CPU繁忙 |
| wa | CPU等待I/O完成的时间 | 磁盘、云盘、NFS、数据库I/O |
| si | 软件中断占用 | 网络流量、软中断处理 |
| st | 虚拟机被宿主机占用的时间 | 云主机宿主资源竞争 |
常见组合如下:
- 负载高、
id很低、us或sy很高:优先排查CPU竞争。 - 负载高、CPU仍有空闲、
wa较高:优先排查磁盘或网络存储。 - 负载高、CPU不高、
wa也不明显:检查D状态任务、内存压力、锁竞争和短时I/O峰值。 - 负载高、
st持续较高:结合云平台监控检查宿主机资源竞争。
不要只看某一秒的 top 输出。间歇性问题至少应持续采样数十秒,并结合故障发生时的业务监控判断。
五、使用vmstat查看运行队列和阻塞任务
执行:
vmstat 1 10
第一行通常是自系统启动以来的平均值,后续行才是每个采样周期的数据。重点关注:
| 字段 | 含义 | 排查方法 |
|---|---|---|
| r | 正在运行或等待CPU的任务数量 | 持续高于逻辑CPU数时关注CPU排队 |
| b | 处于不可中断睡眠的任务数量 | 持续大于0时关注I/O或设备阻塞 |
| si | 每秒从Swap换入的数据 | 持续出现可能存在内存压力 |
| so | 每秒换出到Swap的数据 | 持续出现可能导致明显延迟 |
| bi | 从块设备读取的数据 | 结合磁盘工具判断读压力 |
| bo | 写入块设备的数据 | 结合备份、日志和数据库写入判断 |
| wa | I/O等待占比 | 持续较高时检查存储延迟 |
例如,r持续为10,而服务器只有4个逻辑CPU,同时CPU空闲很低,说明可运行任务正在排队。
如果b持续增加,CPU却没有跑满,则更可能是磁盘、云盘、NFS、文件系统或设备层面发生阻塞。
六、检查处于D状态的进程
Linux进程状态中的 D 通常表示不可中断睡眠。任务可能正在等待内核I/O完成,普通信号不一定能让它立即退出。
查看D状态进程:
ps -eo state,pid,ppid,wchan:32,comm,args | awk '$1 ~ /^D/'
也可以按状态筛选:
ps -eo pid,ppid,user,stat,etime,wchan:32,comm,args | grep -E '^[[:space:]]*[0-9]+.* D'
不同 ps 输出格式可能不同,筛选前应先查看字段位置。重点记录:
- PID和父进程。
- 进程已经阻塞多久。
wchan显示的内核等待位置。- 完整启动参数。
- 进程访问的磁盘、挂载点或网络存储。
查看指定进程的内核栈通常需要root权限:
sudo cat /proc/PID/stack
不要反复对D状态进程执行 kill -9。如果任务正在等待内核I/O,SIGKILL也可能要等到该内核操作返回后才能完成。应继续检查底层磁盘、挂载点、设备错误和远程存储连接。
七、定位等待CPU的高负载进程
查看CPU占用较高的进程:
ps -eo pid,ppid,user,stat,%cpu,%mem,etime,comm,args --sort=-%cpu | head -n 20
持续采样比单次快照更可靠。安装 sysstat 后可执行:
pidstat -u -p ALL -l 1 10
查看每个CPU核心:
mpstat -P ALL 1 10
需要注意以下情况:
- 一个核心持续满载,其他核心空闲:可能是单线程热点或CPU亲和性设置。
- 多个同名工作进程共同占用:单个进程不突出,但总CPU很高。
sy或软中断较高:可能与网络包、系统调用或内核活动有关。- 进程频繁创建和退出:
top可能难以捕捉,应检查cron、systemd timer和任务队列。
对于Java、MySQL、PHP-FPM、Python、Node.js和容器应用,还需要继续定位到线程、SQL、请求或容器内部任务,不能只停留在进程名称。
八、负载高但CPU不高时检查磁盘
安装 sysstat 后,可以查看块设备延迟和队列:
iostat -xz 1 10
不同版本的 iostat 字段可能有所不同,通常应关注:
- 设备读写请求量。
- 平均请求等待时间。
- 设备队列长度。
- 设备繁忙程度。
- 单次I/O大小和吞吐量。
不要只根据 %util 一个字段判断所有存储是否饱和。SSD、云盘、RAID和虚拟块设备的并行能力不同,应结合延迟、队列、吞吐量以及云平台磁盘监控综合判断。
同时检查内核日志:
sudo dmesg -T | tail -n 100
或:
sudo journalctl -k --since "30 minutes ago"
重点寻找:
- I/O error。
- 文件系统错误。
- 磁盘超时或设备重置。
- NFS连接异常。
- 块设备只读。
- 云盘或虚拟设备报错。
如果某个挂载点执行 df、ls 或读取文件时长期卡住,尤其要检查远程文件系统和失联设备。
九、检查内存回收与Swap压力
内存不足不一定立即触发OOM。系统可能先频繁回收页面或进行Swap换入换出,使大量任务变慢并推高负载。
查看内存:
free -h
持续观察:
vmstat 1 10
重点判断:
available是否长期很低。si和so是否持续出现。- 是否有进程内存快速增长。
- 内核日志中是否出现OOM记录。
查看内存占用较高的进程:
ps -eo pid,ppid,user,%mem,rss,etime,comm,args --sort=-rss | head -n 20
检查OOM相关日志:
sudo journalctl -k | grep -i -E 'out of memory|oom-killer|killed process'
直接清理缓存通常不能解决内存泄漏或配置不合理的问题,还可能让后续磁盘读取增加。应先定位内存被谁使用,再决定调整进程配置、修复程序或升级内存。
十、使用PSI判断真实资源压力
较新的Linux内核通常可以通过Pressure Stall Information观察任务因资源竞争而停顿的情况:
cat /proc/pressure/cpu
cat /proc/pressure/memory
cat /proc/pressure/io
输出中的 some 表示至少有部分任务因该资源不足而停顿的时间比例;内存和I/O还可能提供 full,表示所有非空闲任务同时被阻塞的时间比例。
常见判断思路:
cpu压力持续上升:任务因CPU不足而等待。io压力较高:任务被存储或I/O路径阻塞。memory压力较高:内存回收、Swap或内存竞争正在影响任务。
PSI比单独观察Load Average更接近“资源不足实际让任务停顿了多久”,但它仍应与业务延迟、进程状态和设备指标一起使用。部分旧内核或精简系统可能没有这些文件。
十一、常见高负载场景及处理方法
1. Web访问量或恶意请求突然增加
检查访问日志、连接数、接口耗时、CDN数据和防火墙记录。确认是正常流量增长、爬虫、CC攻击,还是某个接口被集中调用。
处理方向包括限流、缓存静态内容、优化热点接口、启用CDN,以及在确认业务增长后增加应用节点。
2. 数据库慢查询或锁等待
数据库进程可能消耗CPU,也可能因磁盘或锁等待造成请求堆积。应检查活动会话、慢查询、锁、索引、连接池和磁盘延迟,不要把重启数据库作为第一步。
3. 备份、压缩或日志任务
备份、文件压缩、日志分析和数据库导出可能同时消耗CPU、内存和I/O。检查:
crontab -l
sudo systemctl list-timers --all
将重任务安排在低峰期,限制并发,并避免多个备份任务在同一时间启动。
4. NFS或网络存储异常
远程存储网络中断、服务端无响应或挂载参数不合适,可能产生大量D状态任务。先确认网络、服务端状态和挂载点,再评估是否需要卸载。对正在被业务使用的挂载点执行强制卸载可能造成数据风险。
5. 容器任务堆积
查看容器资源:
docker stats
继续检查具体容器:
docker top CONTAINER_NAME
docker logs --tail 200 CONTAINER_NAME
容器内大量任务等待同一宿主磁盘时,宿主机负载可能升高,但容器CPU并不突出。还应检查容器存储驱动、日志文件和挂载卷。
6. 云服务器宿主资源竞争
如果 top 中的 st 持续较高,可能是虚拟机等待宿主机分配CPU时间。保存系统采样数据,并结合云平台CPU监控、实例规格和迁移记录判断。持续异常时可联系云服务商或迁移实例。
十二、能不能直接重启或kill进程
重启有时能恢复业务,但会清除现场,也不能解决慢查询、失效存储、异常流量和错误配置。
处理前建议至少保存:
uptime
top -b -n 1
vmstat 1 5
ps -eo pid,ppid,user,stat,%cpu,%mem,etime,wchan:32,comm,args --sort=-%cpu
对普通异常进程,优先通过服务管理器正常停止:
sudo systemctl stop SERVICE_NAME
或先发送可被程序处理的终止信号:
kill -TERM PID
只有确认业务可以承受风险,并且进程无法正常退出时,才考虑 kill -KILL。D状态任务即使收到强制终止信号,也可能在底层I/O返回前继续存在。
十三、推荐的完整排查顺序
遇到Linux服务器负载过高时,可以按以下顺序处理:
- 使用
uptime查看1分钟、5分钟和15分钟负载趋势。 - 使用
nproc确认逻辑CPU数量。 - 使用
top判断CPU是否繁忙,并观察us、sy、wa、st。 - 使用
vmstat 1 10对比运行队列r和阻塞任务b。 - 使用
ps、pidstat和mpstat定位CPU排队的进程或核心。 - 检查D状态进程及其
wchan、内核栈和关联设备。 - 使用
iostat -xz、内核日志和云平台监控检查存储。 - 使用
free、vmstat和OOM日志检查内存与Swap。 - 使用
/proc/pressure/区分CPU、内存和I/O造成的真实停顿。 - 保存故障现场后,再采取限流、停止任务、重启服务、修复配置或扩容措施。
总结
Linux Load Average高并不等于CPU一定跑满。它既可能来自可运行任务排队,也可能来自磁盘、云盘、NFS、内存回收或其他内核I/O导致的不可中断等待。
排查时不要只比较负载值和CPU核心数。更有效的方法是结合 top 的CPU状态、vmstat 的 r 与 b、进程状态、磁盘延迟、Swap活动和PSI资源压力,先确定任务究竟在等待什么。
找到根因后,再针对业务流量、慢查询、备份任务、存储故障、容器配置或实例资源采取措施。这样不仅能恢复服务,也能避免同类高负载问题反复出现。




