首页 Linux教程Linux 系统负载过高排查思路与实战

Linux 系统负载过高排查思路与实战

运维派隶属马哥教育旗下专业运维社区,是国内成立最早的IT运维技术社区,欢迎关注公众号:yunweipai
领取学习更多免费Linux云计算、Python、Docker、K8s教程关注公众号:马哥linux运维

一、问题背景

生产环境中最常遇到的运维场景之一就是服务器负载突然飙升,导致业务响应变慢甚至不可用。监控告警平台频繁报警 Load Average 过高,SSH 登录服务器都变得卡顿。这时候如何快速定位根因、采取有效措施恢复业务,考验的是运维工程师对 Linux 系统资源模型的理解深度和实战经验积累。

很多时候我们会发现,Load Average 高不一定等于 CPU 使用率高,也不一定是内存不足导致。真实原因可能是磁盘 IO 瓶颈、网络流量暴增、僵尸进程堆积、软中断过高、内核任务卡死等多种可能。因此排查负载问题必须建立完整的观察链路和判断逻辑,避免盲目重启服务或者凭感觉调整参数。

本文从实战角度出发,系统梳理 Linux 负载的核心概念、排查路径、工具使用、命令解读、常见根因和修复手段,力求形成完整的排查闭环。

二、适用场景

本文内容适用于以下典型场景:

  • 监控告警显示服务器 Load Average 持续高于正常水平
  • 用户反馈业务响应缓慢或超时
  • SSH 登录服务器明显卡顿
  • 应用日志出现大量慢请求或队列堆积
  • 数据库查询变慢、连接数暴增
  • 容器节点资源使用率异常
  • 定时任务或批处理作业导致系统资源紧张
  • 系统升级、扩容、迁移后性能下降

无论是物理机、虚拟机还是云主机,只要运行的是 Linux 内核,本文的排查思路和命令都适用。

三、核心知识点

3.1 什么是 Load Average

Load Average 是 Linux 系统用来衡量系统繁忙程度的指标,表示在特定时间段内处于可运行状态(R 状态)和不可中断睡眠状态(D 状态)的平均进程数。

通常我们看到的是三个数值,分别代表过去 1 分钟、5 分钟、15 分钟的平均负载。

   bashuptime
# 输出示例:
# 14:23:45 up 10 days, 3:15, 2 users, load average: 2.35, 1.80, 1.50

这里的 2.35, 1.80, 1.50 就是 Load Average。

R 状态进程

处于 Running 或 Runnable 状态的进程,它们正在使用 CPU 或等待 CPU 调度。

D 状态进程

处于不可中断睡眠状态(Uninterruptible Sleep)的进程,通常在等待 IO 操作完成,例如磁盘读写、NFS 挂载卡死等。

这类进程无法被信号中断,也无法被 kill 掉,只能等 IO 完成或者重启系统。

3.2 Load Average 多高算高

这个问题没有绝对标准,需要结合 CPU 核心数判断。

一般规则:

  • Load Average 接近或小于 CPU 核心数:系统正常
  • Load Average 是 CPU 核心数的 1.5 倍以上:需要关注
  • Load Average 是 CPU 核心数的 2 倍以上:已经严重拥堵

例如一台 4 核服务器:

  • Load Average 在 3 以下:正常
  • Load Average 在 4-6 之间:需要排查
  • Load Average 超过 8:严重拥堵

但这只是经验值,还需要结合业务特点和历史基线判断。

3.3 Load Average 高的可能原因

  • CPU 密集型任务过多
  • 磁盘 IO 瓶颈
  • 网络 IO 高
  • 内存不足触发 swap
  • 软中断过高
  • 僵尸进程堆积
  • 内核任务卡死
  • NFS、CIFS 等远程文件系统挂载异常
  • 驱动或硬件故障

3.4 排查原则

  1. 先整体后局部:先看系统整体指标,再看具体进程
  2. 先观察后操作:收集足够信息再做决策
  3. 先排除明显问题:优先排查 CPU、内存、磁盘、网络四大资源
  4. 先非侵入后侵入:优先使用查看类命令,避免一上来就重启服务
  5. 记录现场:保存关键命令输出,便于事后复盘

四、整体排查思路

排查 Load Average 过高问题,推荐按以下流程进行:

   步骤 1:确认负载确实异常
步骤 2:检查 CPU 使用情况
步骤 3:检查内存使用情况
步骤 4:检查磁盘 IO 情况
步骤 5:检查网络流量
步骤 6:检查进程状态分布
步骤 7:定位具体进程
步骤 8:分析进程行为
步骤 9:采取修复措施
步骤 10:验证效果
步骤 11:复盘总结

五、实战步骤

步骤 1:确认负载确实异常

目的

避免误判,先确认 Load Average 确实超出正常范围。

命令

   bashuptime

预期输出

   14:30:12 up 10 days, 3:21, 2 users, load average: 8.56, 7.23, 6.10

异常表现

  • 1 分钟负载远高于 5 分钟和 15 分钟负载:突发性问题
  • 三个负载值都很高且持续上升:持续性问题
  • 负载值超过 CPU 核心数的 2 倍以上

判断逻辑

先确认 CPU 核心数:

   bashgrep -c processor /proc/cpuinfo
# 或者
nproc

假设输出是 4,说明是 4 核服务器。

如果 Load Average 是 8.56,说明平均有 8.56 个进程在等待 CPU 或 IO,已经是核心数的 2 倍以上,属于严重拥堵。

下一步动作

继续排查 CPU 使用情况。


步骤 2:检查 CPU 使用情况

目的

确认 Load Average 高是否由 CPU 使用率高导致。

命令

   bashtop

重点观察第三行 %Cpu(s) 部分:

   %Cpu(s): 85.2 us, 10.5 sy, 0.0 ni, 2.3 id, 1.5 wa, 0.0 hi, 0.5 si, 0.0 st

各字段含义:

  • us:用户空间 CPU 占用
  • sy:内核空间 CPU 占用
  • ni:nice 优先级调整后的用户态 CPU 占用
  • id:空闲 CPU
  • wa:等待 IO 的 CPU 占用
  • hi:硬中断占用
  • si:软中断占用
  • st:虚拟机被宿主机偷走的 CPU 时间

异常表现

  • us 或 sy 很高(超过 80%):CPU 密集型任务过多
  • wa 很高(超过 30%):磁盘 IO 瓶颈
  • si 很高(超过 20%):网络流量大或网卡中断处理不过来
  • id 很低(低于 10%):CPU 已经接近饱和

判断逻辑

如果 id 接近 0,说明 CPU 确实被占满,需要进一步定位是哪些进程在消耗 CPU。

如果 wa 很高,说明很多进程在等待 IO,需要排查磁盘。

如果 si 很高,说明网络中断处理占用了大量 CPU,需要排查网络流量或网卡配置。

下一步动作

如果 CPU 使用率高,跳到步骤 7 定位具体进程。

如果 wa 高,继续步骤 4 检查磁盘 IO。

如果 CPU 使用率不高但 Load Average 高,可能是内存或 IO 问题,继续步骤 3。


步骤 3:检查内存使用情况

目的

确认是否因为内存不足导致频繁 swap,从而拖慢系统。

命令

   bashfree -h

预期输出

                 total        used        free      shared  buff/cache   available
Mem:           7.6G        5.2G        200M        100M        2.2G        2.1G
Swap:          2.0G        1.8G        200M

异常表现

  • Swap 使用率超过 50%
  • available 内存小于 500M
  • used 接近 total

判断逻辑

如果 Swap 使用量很大且 available 内存很少,说明内存不足。

进一步确认是否有频繁 swap in/out:

   bashvmstat 1 5

关注 si 和 so 列:

   procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 3  2 1843200 204800 102400 2252800 5120 3840  1024  2048 8000 12000 65 20 10 5  0
  • si:每秒从 swap 读入内存的数据量(KB)
  • so:每秒从内存写入 swap 的数据量(KB)

如果 si 和 so 持续不为 0 且数值较大,说明系统在频繁 swap,这会严重拖慢系统。

下一步动作

如果确认是内存不足,需要:

  • 定位占用内存最多的进程
  • 考虑扩容内存
  • 优化应用内存使用
  • 调整 swap 策略

继续步骤 7 定位具体进程。


步骤 4:检查磁盘 IO 情况

目的

确认是否因为磁盘 IO 瓶颈导致大量进程处于 D 状态。

命令

   bashiostat -x 1 5

预期输出

   Device            r/s     w/s     rkB/s     wkB/s   rrqm/s   wrqm/s  %rrqm  %wrqm r_await w_await aqu-sz rareq-sz wareq-sz  svctm  %util
sda              50.2   120.5   2048.3   4096.7     5.2     10.5   9.38  8.02    15.3    25.6   3.25    40.8     34.0    8.5   95.2

重点关注:

  • %util:磁盘繁忙程度,接近 100% 说明磁盘已经饱和
  • await:平均每次 IO 请求的等待时间(毫秒),超过 20ms 需要关注
  • r_await:读请求平均等待时间
  • w_await:写请求平均等待时间
  • aqu-sz:平均队列长度,大于 1 说明有排队

异常表现

  • %util 接近或等于 100%
  • await 超过 50ms
  • aqu-sz 大于 5

判断逻辑

如果 %util 接近 100% 且 await 很高,说明磁盘已经成为瓶颈。

需要进一步确认是哪些进程在进行大量 IO 操作。

   bashiotop -o

-o 参数表示只显示正在进行 IO 的进程。

预期输出

   Total DISK READ: 50.2 M/s | Total DISK WRITE: 80.5 M/s
  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND
 1234  be/4  mysql      30.5 M/s    50.2 M/s  0.00 % 85.23 % mysqld
 5678  be/4  root       15.3 M/s    20.1 M/s  0.00 % 45.67 % rsync

可以看到 mysqld 和 rsync 在进行大量磁盘 IO。

下一步动作

如果确认是磁盘 IO 瓶颈,需要:

  • 定位具体进程和 IO 操作类型
  • 检查是否有大文件操作、备份任务、日志写入等
  • 考虑优化应用 IO 模式
  • 考虑升级磁盘或使用 SSD
  • 检查文件系统是否有异常

继续步骤 7 定位具体进程。


步骤 5:检查网络流量

目的

确认是否因为网络流量过大导致软中断过高,从而占用大量 CPU。

命令

   bashsar -n DEV 1 5

预期输出

   14:35:01     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
14:35:02        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00
14:35:02      eth0  15234.50  18567.20  45678.30  67890.50      0.00      0.00      0.00

关注:

  • rxpck/s:每秒接收的数据包数
  • txpck/s:每秒发送的数据包数
  • rxkB/s:每秒接收的数据量(KB)
  • txkB/s:每秒发送的数据量(KB)

异常表现

  • 网络收发包数超过 10 万/秒
  • 网络流量接近带宽上限
  • 网络流量突然暴增

判断逻辑

如果网络流量很大,可能导致网卡软中断过高。

进一步确认软中断情况:

   bashcat /proc/softirqs

关注 NET_RX 和 NET_TX 行,这两行代表网络接收和发送的软中断次数。

如果数值持续快速增长,说明网络软中断很高。

还可以用 top 查看 CPU 的 si 占比:

   bashtop
# 观察 %Cpu(s) 行的 si 值

如果 si 超过 20%,说明软中断占用了较多 CPU。

下一步动作

如果确认是网络流量导致的问题,需要:

  • 定位哪些进程在进行大量网络 IO
  • 检查是否有攻击流量
  • 检查是否有异常连接
  • 考虑优化应用网络模式
  • 考虑启用网卡多队列、RPS、RFS 等优化

继续步骤 7 定位具体进程。


步骤 6:检查进程状态分布

目的

统计各种状态的进程数量,重点关注 R 状态和 D 状态进程。

命令

   bashps -eo stat | sort | uniq -c | sort -rn

预期输出

        45 S
     12 R
      8 D
      5 I
      2 Z
      1 STAT

各状态含义:

  • R:运行或等待运行
  • S:可中断睡眠
  • D:不可中断睡眠(等待 IO)
  • Z:僵尸进程
  • T:停止或被追踪
  • I:空闲内核线程

异常表现

  • R 状态进程数量远超 CPU 核心数
  • D 状态进程数量较多(超过 5 个)
  • Z 状态进程数量较多(超过 10 个)

判断逻辑

如果 D 状态进程很多,说明很多进程在等待 IO,这会导致 Load Average 升高但 CPU 使用率不一定高。

如果 R 状态进程很多,说明 CPU 调度繁忙,需要定位是哪些进程在争抢 CPU。

如果 Z 状态进程很多,说明有大量僵尸进程,虽然不会占用资源,但可能是应用逻辑有问题。

下一步动作

继续步骤 7 定位具体进程。


步骤 7:定位具体进程

目的

找出占用资源最多或状态异常的进程。

方法 1:使用 top 查看 CPU 占用

   bashtop
# 按 P 键按 CPU 使用率排序
# 按 M 键按内存使用率排序

记录 CPU 占用最高的前几个进程的 PID 和命令。

方法 2:使用 ps 查看所有进程

   bashps aux --sort=-%cpu | head -20

按 CPU 使用率倒序排列,显示前 20 个进程。

   bashps aux --sort=-%mem | head -20

按内存使用率倒序排列。

方法 3:查看 D 状态进程

   bashps aux | awk '$8 ~ /D/ {print $0}'

列出所有处于 D 状态的进程。

方法 4:查看僵尸进程

   bashps aux | awk '$8 ~ /Z/ {print $0}'

列出所有僵尸进程。

预期输出

   USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
mysql     1234 85.2 15.3 2048000 1024000 ?    R    10:30  120:45 /usr/sbin/mysqld
www       5678 25.6  8.5 1024000  524288 ?    R    12:15   45:20 /usr/bin/php-fpm

异常表现

  • 某个进程 CPU 占用长期超过 80%
  • 某个进程内存占用超过 50%
  • 有多个进程处于 D 状态
  • 有大量僵尸进程

判断逻辑

记录异常进程的 PID、用户、命令、资源占用情况,继续分析进程行为。

下一步动作

继续步骤 8 分析进程行为。


步骤 8:分析进程行为

目的

深入分析异常进程的具体行为,确认根因。

方法 1:查看进程打开的文件

   bashlsof -p <PID>

可以看到进程打开了哪些文件、socket、设备等。

重点关注:

  • 是否打开了大量文件
  • 是否有文件句柄泄漏
  • 是否访问了远程文件系统
  • 是否有网络连接异常

方法 2:查看进程的系统调用

   bashstrace -p <PID> -c -f

-c 表示统计系统调用次数和耗时,-f 表示跟踪子进程。

Ctrl+C 停止后会输出统计结果:

   % time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 65.23    2.345678      123456        19           read
 20.45    0.734567       12345        60           write
  8.12    0.291234        5678        51           poll
  3.20    0.115012        2345        49           futex
  2.00    0.071890        1234        58           epoll_wait

可以看出进程主要在做什么操作。

如果 read 或 write 占比很高且耗时长,说明在进行大量 IO 操作。

如果 futex 或 epoll_wait 占比高,说明进程在等待锁或事件。

方法 3:查看进程的堆栈

   bashpstack <PID>

输出进程的函数调用堆栈,可以看到进程卡在哪个函数调用上。

方法 4:查看进程的 IO 统计

   bashcat /proc/<PID>/io

输出示例:

   rchar: 123456789
wchar: 987654321
syscr: 12345
syscw: 54321
read_bytes: 102400000
write_bytes: 204800000
cancelled_write_bytes: 0
  • rchar:进程读取的字符数
  • wchar:进程写入的字符数
  • read_bytes:进程实际从磁盘读取的字节数
  • write_bytes:进程实际写入磁盘的字节数

如果 read_bytes 和 write_bytes 很大,说明进程在进行大量磁盘 IO。

方法 5:查看进程的网络连接

   bashlsof -i -a -p <PID>

列出进程的所有网络连接。

或者:

   bashnetstat -antp | grep <PID>

或者:

   bashss -antp | grep <PID>

方法 6:查看进程的线程

   bashps -eLf | grep <PID>

或者:

   bashtop -H -p <PID>

-H 参数表示显示线程。

可以看到进程有多少线程,每个线程的 CPU 和内存占用。

判断逻辑

根据上述信息综合判断:

  • 如果进程在进行大量磁盘 IO,可能是日志写入、数据库查询、文件操作等
  • 如果进程在进行大量网络 IO,可能是网络请求、数据传输等
  • 如果进程 CPU 占用高但系统调用不多,可能是计算密集型任务
  • 如果进程有大量网络连接,可能是连接池耗尽、连接泄漏等
  • 如果进程打开了大量文件,可能是文件句柄泄漏

下一步动作

根据分析结果,采取相应的修复措施。


步骤 9:采取修复措施

场景 1:某个进程 CPU 占用过高

临时措施

降低进程优先级:

   bashrenice +10 -p <PID>

这会降低进程的调度优先级,让其他进程有更多机会获得 CPU。

根本措施
  • 优化应用代码逻辑
  • 检查是否有死循环、频繁计算等问题
  • 考虑限流、降级、熔断等保护机制
  • 考虑扩容或负载均衡
风险提醒

renice 只是临时缓解,不能解决根本问题。

如果直接 kill 进程,需要确认业务影响和重启方案。

场景 2:内存不足导致频繁 swap

临时措施

清理缓存:

   bashsync
echo 3 > /proc/sys/vm/drop_caches

sync 确保脏页写入磁盘,echo 3 清理 page cache、dentries 和 inodes。

风险提醒

清理缓存会导致后续文件 IO 变慢,因为需要重新读取文件到内存。

生产环境慎用,仅在内存极度紧张且确认缓存占用过多时使用。

根本措施
  • 定位占用内存最多的进程
  • 优化应用内存使用
  • 考虑扩容内存
  • 调整 swappiness 参数:
   bashcat /proc/sys/vm/swappiness
# 默认值通常是 60

# 临时调整
echo 10 > /proc/sys/vm/swappiness

# 永久调整
echo "vm.swappiness = 10" >> /etc/sysctl.conf
sysctl -p

swappiness 值越小,系统越倾向于使用物理内存而不是 swap。

但设置过低可能导致内存不足时系统变得更慢。

场景 3:磁盘 IO 瓶颈

临时措施

暂停或限速正在进行的大文件操作、备份任务、日志归档等。

如果是某个进程导致的,可以用 ionice 降低其 IO 优先级:

   bashionice -c3 -p <PID>

-c3 表示 Idle 调度类,只有在没有其他 IO 请求时才会执行。

根本措施
  • 优化应用 IO 模式,减少随机读写
  • 使用 SSD 代替机械硬盘
  • 增加磁盘缓存
  • 检查文件系统是否有碎片
  • 检查是否有慢查询导致数据库 IO 过高
  • 检查日志轮转配置,避免单个日志文件过大

场景 4:网络流量过大导致软中断高

临时措施

限制网络流量或暂停非关键服务。

根本措施
  • 启用网卡多队列:
   bashethtool -l eth0
# 查看网卡队列数

ethtool -L eth0 combined 4
# 设置为 4 个队列
  • 启用 RPS(Receive Packet Steering):
   bashecho f > /sys/class/net/eth0/queues/rx-0/rps_cpus
  • 启用 RFS(Receive Flow Steering):
   bashecho 32768 > /proc/sys/net/core/rps_sock_flow_entries
echo 2048 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt
  • 优化应用网络模型,减少短连接
  • 考虑使用负载均衡分散流量

场景 5:D 状态进程堆积

原因分析

进程处于 D 状态通常是在等待 IO 操作完成,常见原因:

  • 磁盘故障或慢盘
  • NFS 挂载超时或卡死
  • iSCSI 存储异常
  • 驱动或内核 bug
排查方法

查看 D 状态进程的堆栈:

   bashcat /proc/<PID>/stack

输出示例:

   [<0>] wait_on_page_bit_common+0x123/0x456
[<0>] __filemap_get_folio+0x234/0x567
[<0>] ext4_write_begin+0x345/0x678
[<0>] generic_perform_write+0x456/0x789
[<0>] ext4_buffered_write_iter+0x567/0x890
[<0>] ext4_file_write_iter+0x678/0x901
[<0>] new_sync_write+0x789/0x012
[<0>] vfs_write+0x890/0x123
[<0>] ksys_write+0x901/0x234
[<0>] __x64_sys_write+0x012/0x345
[<0>] do_syscall_64+0x123/0x456
[<0>] entry_SYSCALL_64_after_hwframe+0x234/0x567

可以看到进程卡在文件写入操作上。

临时措施

如果是 NFS 挂载问题,尝试强制卸载:

   bashumount -f /mnt/nfs
# 或者
umount -l /mnt/nfs

-f 表示强制卸载,-l 表示延迟卸载。

风险提醒

强制卸载可能导致数据丢失,慎用。

如果 D 状态进程无法清理,可能只能重启系统。

根本措施
  • 检查磁盘健康状态:
   bashsmartctl -a /dev/sda
  • 检查 NFS 配置和网络连接
  • 检查存储设备是否正常
  • 考虑更换故障硬件

场景 6:僵尸进程堆积

原因分析

僵尸进程是子进程已经退出,但父进程没有调用 wait() 或 waitpid() 回收子进程资源。

僵尸进程不会占用 CPU 和内存,但会占用进程号,数量过多可能导致无法创建新进程。

排查方法

找到僵尸进程的父进程:

   bashps -ef | grep defunct

或者:

   bashps -eo pid,ppid,stat,comm | awk '$3 ~ /Z/ {print $0}'

记录父进程的 PID(PPID 列)。

修复措施

给父进程发送 SIGCHLD 信号,提示其回收子进程:

   bashkill -s SIGCHLD <父进程PID>

如果父进程本身有 bug 无法回收,只能重启父进程:

   bashkill <父进程PID>
# 或者强制杀掉
kill -9 <父进程PID>
风险提醒

重启父进程前需要确认业务影响。

根本措施

修复应用代码,确保正确处理子进程退出。


步骤 10:验证效果

目的

确认修复措施是否有效,负载是否恢复正常。

命令

再次检查 Load Average:

   bashuptime

再次检查 CPU、内存、磁盘、网络:

   bashtop
free -h
iostat -x 1 5
sar -n DEV 1 5

预期结果

  • Load Average 下降到正常范围
  • CPU idle 比例上升
  • 磁盘 %util 下降
  • 内存 swap 使用率下降
  • D 状态进程数量减少

异常表现

如果负载仍然很高,说明问题没有解决或者还有其他根因,需要继续排查。

下一步动作

如果问题解决,继续步骤 11 复盘总结。

如果问题未解决,回到步骤 2 重新排查。


步骤 11:复盘总结

目的

记录排查过程、根因、修复措施、验证结果,便于后续参考和改进。

复盘要点

  • 问题触发时间和表现
  • 监控告警内容
  • 排查路径和关键命令
  • 定位的根因
  • 采取的修复措施
  • 验证结果
  • 是否需要优化监控告警
  • 是否需要优化应用架构
  • 是否需要扩容或升级硬件

复盘输出

形成故障报告或知识库文档,包含:

  • 问题描述
  • 影响范围
  • 根因分析
  • 修复措施
  • 预防措施
  • 经验教训

六、常用命令

以下是排查 Load Average 过高时常用的命令,按场景分类。

6.1 查看负载和运行时间

   bashuptime

6.2 查看 CPU 信息

   bash# 查看 CPU 核心数
grep -c processor /proc/cpuinfo
nproc

# 查看 CPU 详细信息
lscpu

# 查看 CPU 使用情况
top
htop

# 查看 CPU 历史数据
sar -u 1 5

6.3 查看内存信息

   bash# 查看内存使用情况
free -h

# 查看内存详细统计
cat /proc/meminfo

# 查看 swap 使用情况
swapon -s

# 查看内存交换统计
vmstat 1 5

6.4 查看磁盘 IO 信息

   bash# 查看磁盘 IO 统计
iostat -x 1 5

# 查看各进程磁盘 IO
iotop -o

# 查看磁盘使用情况
df -h

# 查看 inode 使用情况
df -i

# 查看磁盘健康状态
smartctl -a /dev/sda

6.5 查看网络信息

   bash# 查看网络流量
sar -n DEV 1 5
ifstat
nload

# 查看网络连接
netstat -antp
ss -antp

# 查看网卡队列
ethtool -l eth0

# 查看软中断统计
cat /proc/softirqs

6.6 查看进程信息

   bash# 查看所有进程
ps aux
ps -ef

# 按 CPU 使用率排序
ps aux --sort=-%cpu | head -20

# 按内存使用率排序
ps aux --sort=-%mem | head -20

# 查看进程状态分布
ps -eo stat | sort | uniq -c | sort -rn

# 查看 D 状态进程
ps aux | awk '$8 ~ /D/ {print $0}'

# 查看僵尸进程
ps aux | awk '$8 ~ /Z/ {print $0}'

# 查看进程树
pstree -p

# 查看进程详细信息
top -p <PID>
htop -p <PID>

6.7 分析进程行为

   bash# 查看进程打开的文件
lsof -p <PID>

# 查看进程的网络连接
lsof -i -a -p <PID>

# 查看进程的系统调用
strace -p <PID> -c -f

# 查看进程的堆栈
pstack <PID>
cat /proc/<PID>/stack

# 查看进程的 IO 统计
cat /proc/<PID>/io

# 查看进程的线程
ps -eLf | grep <PID>
top -H -p <PID>

# 查看进程的状态
cat /proc/<PID>/status

# 查看进程的命令行
cat /proc/<PID>/cmdline

# 查看进程的环境变量
cat /proc/<PID>/environ

6.8 调整进程优先级

   bash# 降低进程 CPU 优先级
renice +10 -p <PID>

# 降低进程 IO 优先级
ionice -c3 -p <PID>

6.9 内存管理

   bash# 清理缓存(慎用)
sync
echo 3 > /proc/sys/vm/drop_caches

# 查看和调整 swappiness
cat /proc/sys/vm/swappiness
echo 10 > /proc/sys/vm/swappiness

# 查看内存大页
cat /proc/meminfo | grep -i huge

6.10 系统信息

   bash# 查看内核版本
uname -r

# 查看系统版本
cat /etc/os-release

# 查看系统日志
journalctl -xe
dmesg | tail -50

# 查看负载历史
sar -q 1 5

七、配置示例

7.1 优化 swap 使用策略

编辑 /etc/sysctl.conf

   ini# 降低 swap 使用倾向
vm.swappiness = 10

# 增加脏页刷新频率
vm.dirty_background_ratio = 5
vm.dirty_ratio = 10

使配置生效:

   bashsysctl -p

7.2 启用网卡多队列

查看网卡支持的队列数:

   bashethtool -l eth0

输出示例:

   Channel parameters for eth0:
Pre-set maximums:
RX:             4
TX:             4
Other:          0
Combined:       4
Current hardware settings:
RX:             1
TX:             1
Other:          0
Combined:       1

设置为最大队列数:

   bashethtool -L eth0 combined 4

7.3 启用 RPS 和 RFS

RPS 配置(以 4 核服务器为例):

   bash# 设置 RPS CPU 掩码(0xf 表示使用 CPU 0-3)
echo f > /sys/class/net/eth0/queues/rx-0/rps_cpus

RFS 配置:

   bash# 设置全局流表大小
echo 32768 > /proc/sys/net/core/rps_sock_flow_entries

# 设置每个队列的流表大小
echo 2048 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt

7.4 调整文件描述符限制

编辑 /etc/security/limits.conf

   * soft nofile 65536
* hard nofile 65536
* soft nproc 32768
* hard nproc 32768

编辑 /etc/sysctl.conf

   ini# 系统级文件描述符限制
fs.file-max = 6553560

使配置生效:

   bashsysctl -p

重新登录生效。

7.5 调整内核参数

编辑 /etc/sysctl.conf

   ini# 增加最大连接数
net.core.somaxconn = 32768

# 增加 TCP 连接队列
net.ipv4.tcp_max_syn_backlog = 8192

# 启用 TCP 时间戳
net.ipv4.tcp_timestamps = 1

# 启用 TCP 窗口扩展
net.ipv4.tcp_window_scaling = 1

# 减少 TIME_WAIT 状态连接数
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30

# 增加本地端口范围
net.ipv4.ip_local_port_range = 10000 65000

使配置生效:

   bashsysctl -p

八、日志或指标观察方法

8.1 系统日志

   bash# 查看系统日志最后 50 行
journalctl -xe | tail -50

# 查看内核日志
dmesg | tail -50

# 持续监控系统日志
journalctl -f

关注关键字:

  • Out of memory:内存不足
  • I/O error:磁盘 IO 错误
  • segfault:进程段错误
  • hung task:进程卡死
  • soft lockup:软锁死
  • hard lockup:硬锁死

8.2 应用日志

根据应用不同,日志路径不同。常见路径:

  • Nginx:/var/log/nginx/error.log
  • Apache:/var/log/httpd/error_log
  • MySQL:/var/log/mysql/error.log
  • Redis:/var/log/redis/redis-server.log
  • PHP-FPM:/var/log/php-fpm/error.log

8.3 监控指标

如果使用 Prometheus + Grafana 监控,重点关注:

  • node_load1node_load5node_load15:Load Average
  • node_cpu_seconds_total:CPU 使用时间
  • node_memory_MemAvailable_bytes:可用内存
  • node_memory_SwapCached_bytes:Swap 使用量
  • node_disk_io_time_seconds_total:磁盘 IO 时间
  • node_disk_read_bytes_total:磁盘读字节数
  • node_disk_written_bytes_total:磁盘写字节数
  • node_network_receive_bytes_total:网络接收字节数
  • node_network_transmit_bytes_total:网络发送字节数

以上指标名称仅供参考,实际指标名称取决于使用的 exporter 版本。


九、排查路径

以下是几种典型场景的完整排查路径。

场景 1:Load Average 高且 CPU 使用率高

   步骤 1:uptime 确认负载高
步骤 2:top 确认 CPU 使用率高
步骤 3:ps aux --sort=-%cpu 找出 CPU 占用最高的进程
步骤 4:lsof -p <PID> 查看进程打开的文件和连接
步骤 5:strace -p <PID> -c 查看系统调用
步骤 6:分析进程行为,确认是否正常
步骤 7:如果是计算密集型任务,考虑优化代码或扩容
步骤 8:如果是异常进程,考虑重启或 kill
步骤 9:验证负载是否恢复

场景 2:Load Average 高但 CPU 空闲

   步骤 1:uptime 确认负载高
步骤 2:top 确认 CPU idle 高但 wa 也高
步骤 3:iostat -x 1 5 确认磁盘 IO 瓶颈
步骤 4:iotop -o 找出 IO 占用最高的进程
步骤 5:lsof -p <PID> 查看进程访问的文件
步骤 6:检查是否有大文件操作、备份任务等
步骤 7:如果是日志写入过多,考虑调整日志级别或轮转策略
步骤 8:如果是数据库慢查询,优化 SQL 或加索引
步骤 9:验证负载是否恢复

场景 3:有多个 D 状态进程

   步骤 1:ps aux | awk '$8 ~ /D/ {print $0}' 找出 D 状态进程
步骤 2:cat /proc/<PID>/stack 查看进程堆栈
步骤 3:确认进程卡在哪个系统调用上
步骤 4:如果是磁盘 IO,检查磁盘健康状态
步骤 5:如果是 NFS 挂载,检查网络和 NFS 服务
步骤 6:尝试强制卸载或重启相关服务
步骤 7:如果无法解决,可能需要重启系统

场景 4:软中断过高

   步骤 1:top 确认 si 占比很高
步骤 2:cat /proc/softirqs 确认是网络软中断
步骤 3:sar -n DEV 1 5 确认网络流量很大
步骤 4:netstat -antp 或 ss -antp 查看网络连接
步骤 5:找出占用网络最多的进程
步骤 6:ethtool -l eth0 查看网卡队列配置
步骤 7:启用网卡多队列、RPS、RFS
步骤 8:验证软中断是否下降

场景 5:内存不足频繁 swap

   步骤 1:free -h 确认内存不足且 swap 使用率高
步骤 2:vmstat 1 5 确认有频繁的 si 和 so
步骤 3:ps aux --sort=-%mem 找出内存占用最高的进程
步骤 4:分析进程内存使用是否合理
步骤 5:考虑优化应用内存使用或扩容内存
步骤 6:临时清理缓存缓解(慎用)
步骤 7:调整 swappiness 参数
步骤 8:验证 swap 使用率是否下降

十、风险提醒

10.1 清理缓存风险

执行 echo 3 > /proc/sys/vm/drop_caches 会清理 page cache、dentries 和 inodes,可能导致:

  • 后续文件 IO 变慢,需要重新从磁盘读取
  • 正在进行的 IO 操作可能受影响
  • 数据库性能短时间内下降

建议:

  • 生产环境慎用
  • 仅在内存极度紧张且确认缓存占用过多时使用
  • 在业务低峰期执行

10.2 强制 kill 进程风险

使用 kill -9 <PID> 强制杀掉进程可能导致:

  • 数据丢失或损坏
  • 锁文件未清理
  • 子进程变成孤儿进程
  • 服务无法正常重启

建议:

  • 优先使用 kill <PID> 让进程优雅退出
  • 确认业务影响和重启方案
  • 检查是否有备份

10.3 强制卸载文件系统风险

使用 umount -f 或 umount -l 强制卸载文件系统可能导致:

  • 正在访问该文件系统的进程崩溃
  • 数据丢失
  • 文件系统损坏

建议:

  • 优先确认没有进程在使用该文件系统
  • 使用 lsof /mnt/path 或 fuser -m /mnt/path 查看使用情况
  • 考虑先停止相关服务

10.4 调整内核参数风险

修改 /etc/sysctl.conf 中的内核参数需要谨慎,错误的参数可能导致:

  • 系统不稳定
  • 网络连接异常
  • 性能下降

建议:

  • 先在测试环境验证
  • 修改前备份原配置
  • 逐个参数调整并观察效果
  • 记录修改原因和预期效果

10.5 重启服务风险

重启服务可能导致:

  • 业务中断
  • 用户请求失败
  • 数据丢失

建议:

  • 先评估业务影响
  • 选择业务低峰期操作
  • 提前通知相关人员
  • 准备回滚方案
  • 监控服务重启后状态

十一、验证方式

11.1 验证负载是否恢复

   bashuptime
# 观察 Load Average 是否下降到正常范围

连续观察几分钟,确认负载持续下降或保持稳定。

11.2 验证 CPU 使用率是否正常

   bashtop
# 观察 %Cpu(s) 行的 id 值是否上升
# 观察 wa、si 等值是否下降

11.3 验证内存使用是否改善

   bashfree -h
# 观察 available 内存是否增加
# 观察 swap 使用量是否下降

11.4 验证磁盘 IO 是否缓解

   bashiostat -x 1 5
# 观察 %util 是否下降
# 观察 await 是否下降

11.5 验证网络流量是否正常

   bashsar -n DEV 1 5
# 观察 rxpck/s 和 txpck/s 是否恢复正常水平

11.6 验证软中断是否下降

   bashtop
# 观察 %Cpu(s) 行的 si 值是否下降

11.7 验证进程状态是否正常

   bashps -eo stat | sort | uniq -c | sort -rn
# 观察 D 状态进程是否减少
# 观察 R 状态进程是否在合理范围

11.8 验证业务是否恢复

  • 检查应用日志是否还有大量错误
  • 检查用户反馈是否恢复正常
  • 检查监控面板是否恢复正常
  • 进行业务功能验证

十二、回滚方案

12.1 内核参数调整回滚

如果修改 /etc/sysctl.conf 后系统异常,回滚方法:

   bash# 恢复备份的配置文件
cp /etc/sysctl.conf.bak /etc/sysctl.conf

# 使配置生效
sysctl -p

或者直接修改单个参数:

   bash# 恢复 swappiness 为默认值
echo 60 > /proc/sys/vm/swappiness

12.2 网卡配置回滚

如果修改网卡队列或 RPS 配置后网络异常,回滚方法:

   bash# 恢复网卡队列为默认值
ethtool -L eth0 combined 1

# 清空 RPS 配置
echo 0 > /sys/class/net/eth0/queues/rx-0/rps_cpus

12.3 服务重启回滚

如果重启服务后问题更严重,回滚方法:

  • 如果有服务版本管理,回滚到上一个稳定版本
  • 如果有配置文件备份,恢复旧配置
  • 如果有数据备份,恢复数据
  • 如果有完整的快照,考虑从快照恢复

12.4 进程 kill 回滚

如果 kill 进程后发现影响业务,回滚方法:

   bash# 重新启动进程
systemctl start <service_name>

# 或者手动启动
/path/to/binary &

确认服务启动后:

  • 检查进程是否正常运行
  • 检查日志是否有错误
  • 验证业务功能

十三、生产环境注意事项

13.1 操作前检查

  • 确认当前是否业务高峰期
  • 确认是否有重要任务正在执行
  • 确认是否有备份
  • 确认回滚方案是否可行
  • 确认相关人员是否知晓

13.2 操作中监控

  • 持续观察监控面板
  • 持续观察应用日志
  • 持续观察系统日志
  • 准备随时回滚

13.3 操作后验证

  • 验证负载是否恢复
  • 验证业务是否正常
  • 验证监控是否正常
  • 记录操作过程和结果

13.4 权限控制

  • 生产环境操作需要审批
  • 重要操作需要双人确认
  • 记录操作日志
  • 避免直接使用 root 用户

13.5 变更管理

  • 遵循变更流程
  • 记录变更内容
  • 记录变更原因
  • 记录变更影响
  • 记录回滚方案

13.6 应急预案

  • 准备应急联系人列表
  • 准备应急处理流程
  • 准备常用命令清单
  • 定期演练应急流程

十四、总结

排查 Linux 系统负载过高问题是运维工程师的基本功,需要掌握以下几点:

14.1 理解核心概念

  • Load Average 反映的是可运行和不可中断睡眠状态的进程数
  • 需要结合 CPU 核心数判断负载是否正常
  • Load Average 高不一定是 CPU 高,也可能是 IO 瓶颈

14.2 建立排查路径

  • 先整体后局部
  • 先观察后操作
  • 先排除明显问题
  • 先非侵入后侵入
  • 记录现场

14.3 熟练使用工具

  • uptimetophtop:查看负载和 CPU
  • freevmstat:查看内存和 swap
  • iostatiotop:查看磁盘 IO
  • sarnetstatss:查看网络
  • pslsofstracepstack:分析进程

14.4 掌握分析方法

  • 根据 CPU、内存、磁盘、网络四大资源分类排查
  • 关注进程状态分布,重点关注 R 和 D 状态
  • 深入分析异常进程的系统调用、打开文件、网络连接
  • 综合多个指标判断根因

14.5 采取有效措施

  • 临时措施:降低优先级、清理缓存、限速等
  • 根本措施:优化代码、调整配置、扩容资源
  • 高风险操作需要评估影响、准备回滚
  • 生产环境操作需要遵循变更流程

14.6 形成闭环

  • 修复后必须验证效果
  • 准备回滚方案
  • 记录排查过程和结果
  • 形成故障报告和知识沉淀
  • 优化监控告警和预防机制

只有经过大量实战积累,才能在生产环境故障时快速定位问题、采取正确措施、恢复业务正常。本文提供的是系统化的排查思路和工具方法,需要结合具体业务场景和系统特点灵活运用。

Linux 系统负载过高排查思路与实战插图

本文链接:https://www.yunweipai.com/archives/49403

网友评论comments

发表回复

您的电子邮箱地址不会被公开。

暂无评论

Copyright © 2012-2022 YUNWEIPAI.COM - 运维派 京ICP备16064699号-6
扫二维码
扫二维码
返回顶部