0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

服务器负载过高的系统性排查方法

马哥Linux运维 来源:马哥Linux运维 2026-05-08 14:26 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

问题背景

2025 年 6 月,某电商平台在年中促销活动期间,线上 Web 服务器(配置 24 核 CPU / 32GB 内存)于 14:30 左右触发 CPU 负载告警。监控数据显示 load average 从正常值 5~8 飙升至 42+,同时业务监控显示接口 P99 响应时间从 200ms 升高到 3800ms,用户侧开始出现超时和 502 错误。

本文以这次故障的完整排查过程为线索,展示服务器负载过高的系统性排查方法。文章以第一人称叙事展开,每步都给出实际命令输出和决策思路。

一、接到告警:第一反应

收到告警后,登录服务器执行第一个命令:

$ uptime
1445 up 15 days, 6:12, 3 users, load average: 42.35, 28.17, 15.42

load average 的三个值分别是 1 分钟 / 5 分钟 / 15 分钟的平均负载。42.35 对于 24 核的服务器意味着平均每个 CPU 核上有 1.76 个任务在竞争——CPU 已经饱和。

但负载高不等于 CPU 使用率高,需要进一步区分瓶颈类型。

二、全局扫描:定性瓶颈类型

2.1 top —— 看 CPU 时间分布

$ top
top - 1450 up 15 days, 6:12, 3 users, load average: 42.35, 28.17, 15.42
Tasks: 325 total,  4 running, 321 sleeping,  0 stopped,  0 zombie
%Cpu(s): 8.5 us, 5.2 sy, 0.0 ni, 32.1 id, 53.8 wa, 0.0 hi, 0.4 si, 0.0 st
MiB Mem : 31967.6 total,  4284.5 free, 14234.2 used, 13448.9 buff/cache
MiB Swap:  4096.0 total,  945.2 free,  3150.8 used. 13233.4 avail Mem

 PID USER   PR NI  VIRT  RES  SHR S %CPU %MEM   TIME+ COMMAND
5678 www    20  0 0.356t 0.042t 32768 S  2.2  0.6 12:34.56 java
2345 root   20  0 175240  5300  4212 S  1.8  0.1  2:15.30 nginx

最关键的发现是 **wa(I/O 等待)= 53.8%**,说明大量 CPU 时间在等待 I/O 完成。结合 id(空闲)= 32.1%,说明 CPU 并没有满载(us + sy = 13.7%),但系统负载高的原因是 I/O 阻塞导致进程排队。

这是典型的"负载高因为 I/O 瓶颈"场景——CPU 有空闲时间,但进程在等 I/O 完成,所以 load average 中的"等待进程"数量很高。

2.2 vmstat —— 确认阻塞情况

$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b  swpd  free  buff cache  si  so  bi  bo in cs us sy id wa st
3 38 204800 42845  ...

b列(不可中断睡眠进程数)为 38,说明有 38 个进程阻塞在 I/O 上。r列(运行队列)为 3,说明 CPU 调度并没有明显积压。

判断:系统瓶颈在 I/O 子系统,不是 CPU。

2.3 free —— 检查内存和 swap

$ free -h -w
       total    used    available   buffers   cache
Mem:      31G     14G      13G     2.2G     11G
Swap:     4.0G     3.0G     1.0G

available 内存 13G,不是内存瓶颈。但 swap 使用了 3GB,说明存在一定程度的内存压力,进程被换出到磁盘,可能加重 I/O 负担。

2.4 第一阶段小结

全局扫描结论:

瓶颈类型:I/O 瓶颈(wa=53.8%,b=38)

资源情况:CPU 有余量(id=32.1%),内存充足,swap 有少量使用

方向:下一步定位哪个进程在产生大量 I/O

三、定位 I/O 来源

3.1 iostat —— 看磁盘到底有多忙

$ iostat -xdm 1 3
Linux 5.15.0-91-generic ... 06/15/2025 _x86_64_ (24 CPU)

Device   r/s   w/s   rkB/s   wkB/s r_await w_await aqu-sz %util
vda   120.5 4500.3  3840.0 360000.0   2.1  112.3  248.5  98.7

关键指标解读:

w/s = 4500:每秒 4500 次写请求,非常高

w_await = 112.3ms:每次写请求平均等待 112ms,远高于 SSD 的正常范围(<2ms)

aqu-sz = 248.5:平均队列长度 248,说明 IO 请求大量积压

**%util = 98.7%**:磁盘接近饱和

这是一块通用型 SSD 云盘(极速型 SSD 的 IOPS 上限一般在 2 万左右,但 4500 w/s 不至于打到上限)。112ms 的写延迟说明单次写入遇到了抖动——可能是磁盘层的资源争抢或日志落盘的大量小 IO。

# 查看磁盘队列深度(内核侧)
$ cat /sys/block/vda/queue/nr_requests
256

# 查看调度器
$ cat /sys/block/vda/queue/scheduler
[mq-deadline] none

3.2 iotop —— 找到 I/O 最多的进程

$ iotop -o
Total DISK READ: 3.84 M/s | Total DISK WRITE: 360.00 M/s
 TID PRIO USER   DISK READ DISK WRITE SWAPIN   IO>  COMMAND
3456 be/4 root    0.00 B/s 320.00 M/s 0.00 % 95.20 % java
5678 be/4 www    3.84 M/s  0.00 B/s 0.00 %  2.10 % nginx

Java 进程以 320MB/s 的速度在写入磁盘,几乎占了全部 IO。IO> 列显示该进程 95.2% 的时间在等待 I/O。

3.3 pidstat -d —— 按进程确认

$ pidstat -d 1 3
Linux ... 06/15/2025 _x86_64_ (24 CPU)

1422   PID  kB_rd/s  kB_wr/s kB_ccwr/s Command
1423   3456   0.00 320000.00  0.00   java

3.4 确认文件级写入

用lsof看 Java 进程打开了哪些文件在写:

$ ls -la /proc/3456/fd/ | grep -E'REG.*W'| sort -k7 -rn | head -5
lrwx------ 1 root root 64 Jun 15 14:33 23 -> /var/log/app/app.log
lrwx------ 1 root root 64 Jun 15 14:33 24 -> /var/log/app/app.log.1
lrwx------ 1 root root 64 Jun 15 14:33 25 -> /var/log/app/error.log

关键发现:进程打开了app.log.1(轮转后的日志文件)—— 这意味着日志轮转后旧文件被重命名,但 Java 进程仍在往旧文件中写入。

# 检查这些 fd 是否已被删除
$ ls -la /proc/3456/fd/23
... /var/log/app/app.log (deleted)
$ ls -la /proc/3456/fd/24
... /var/log/app/app.log.1

确认第 23 号 fd 对应的文件已被删除(logrotatecreate方式导致),而第 24 号 fd 对应的app.log.1文件仍在写入。

四、根因确认

4.1 排查发现

完整排查后,根因链路如下:

应用日志配置为 DEBUG 级别:促销活动期间开发团队在线开启了 debug 日志,日志写入量从平时的 20MB/min 暴增到 20GB/min。

logrotate 使用 create 而非 copytruncate:默认的 logrotate 配置是create,轮转时执行mv app.log app.log.1+create new app.log。Java 进程持有的旧文件句柄仍然指向app.log.1(即被重命名后的文件),所以日志继续向app.log.1写入。

写放大效应:日志写入量激增 + 双文件写入(app.log和app.log.1)→ 磁盘写 IO 打满 → 所有需要磁盘 I/O 的进程排队(包括数据库持久化、session 持久化)→ load average 飙升 → 业务响应变慢。

# 确认日志文件大小
$ ls -lh /var/log/app/
-rw-r--r-- 1 root root 5.2G Jun 15 14:34 app.log
-rw-r--r-- 1 root root 4.8G Jun 15 14:34 app.log.1

# 确认 logrotate 配置
$ cat /etc/logrotate.d/app
/var/log/app/*.log{
  daily
  rotate 7
  create   # <- 问题在这里,应该用 copytruncate
    compress
    delaycompress
    missingok
    notifempty
}

4.2 立即恢复操作

第一步:让 Java 进程释放旧文件句柄,释放 deleted 文件的磁盘空间

# 查找 Java 进程 PID
$ ps aux | grep java
# 发送 USR1 信号让 log4j2 重新加载配置(大多数日志框架支持)
$kill-USR1 

# 验证空间是否释放
$ df -h /

如果kill -USR1无效,可以用lsof确认哪个 fd 是 deleted 文件,然后清空:

# 找到 deleted 文件的 fd 编号
$ sudo lsof -p  | grep'(deleted)'
$ : > /proc//fd/

第二步:关闭 DEBUG 日志

修改 log4j2.xml 或 logback.xml,将日志级别恢复为 WARN 或 INFO,然后重新加载配置。

第三步:确认 IO 恢复正常

$ iostat -xdm 1 3
$ uptime

15 分钟后负载恢复到正常水平。

4.3 根本解决方案

修改 logrotate 配置,使用copytruncate:

/var/log/app/*.log{
  daily
  rotate 30
  copytruncate
  compress
  delaycompress
  missingok
  notifempty
}

配置异步日志写入(log4j2 AsyncAppender / logback AsyncAppender),避免日志 I/O 阻塞业务线程。

将 /var/log 独立分区,避免日志写满根分区。

日志级别变更流程化:生产环境日志级别变更需审批,变更完成后自动恢复。

五、附加生产故障案例

上述案例是 I/O 阻塞型负载过高的典型场景。以下是另外三种在线上环境中反复出现的负载过高案例,供对比参考。

案例 A:数据库双 1 配置拖死磁盘

场景:某 MySQL 实例在业务高峰时 load 飙高到 60+,wa 持续在 70~80%。

$ iostat -xdm 1
sda  w/s=12000 w_await=92ms %util=99.5%

根因:innodb_flush_log_at_trx_commit=1(每次事务提交都刷盘)+sync_binlog=1(每次提交同步 binlog),在高并发事务下,磁盘 fsync 成为瓶颈。

-- 临时降低持久化级别(风险:丢失 1 秒内的事务)
SET GLOBAL innodb_flush_log_at_trx_commit=2;
SET GLOBAL sync_binlog=1000;

长期方案:

升级更高 IOPS 的云盘(如 ESSD PL3)

开启组提交(group commit),MySQL 5.7+ 默认支持

考虑 semi-sync 复制代替强同步

案例 B:TIME_WAIT 堆积导致连接失败

场景:高并发短连接服务,load 上升到 9.2(16 核),业务开始报 Connection refused。

$ ss -s
Total: 65200 (kernel 65321)
TCP:  62134 (estab 12, closed 62000, orphaned 8, synrecv 0, timewait 62000)

$ netstat -s | grep"listen"
  18432timesthe listen queue of a socket overflowed

根因:短连接场景下 TIME_WAIT 堆积到 62000,占满了系统连接表,新的连接无法建立。

# 立即缓解
$ sysctl -w net.ipv4.tcp_tw_reuse=1
$ sysctl -w net.ipv4.tcp_fin_timeout=15

长期方案:客户端改用长连接池或连接复用。

案例 C:apt-check 后台进程 IO 打满(小内存服务器)

场景:低配云服务器(2 核 4GB)运行中突然 load 飙高到 15+,wa > 90%。

$ iotop -o
 TID PRIO USER   DISK READ DISK WRITE SWAPIN   IO>  COMMAND
1234 be/4 root   84.00 M/s  0.00 B/s 0.00 % 98.5 % apt-check

根因:Ubuntu 的unattended-upgrades自动更新检查服务触发,导致大量磁盘读操作。小内存服务器上磁盘 I/O 更容易成为瓶颈。

# 临时停止
$ systemctl stop apt-daily.timer

# 永久关闭(如果不需要自动更新)
$ systemctldisableapt-daily.timer
$ systemctldisableapt-daily-upgrade.timer

六、Netflix 60 秒法则在实战中的应用

本次排查过程中使用的正是 Netflix 性能工程团队总结的"60 秒法则"——登录服务器后的前 60 秒内执行一组标准命令,快速建立整体认知。以下是针对负载过高场景的命令序列:

# 第 1~5 秒
uptime                 # load average
dmesg -T | tail -10          # kernel errors

# 第 6~15 秒
vmstat 1 3               # procs/memory/io/system/cpu
mpstat -P ALL 1 3           # per-CPU breakdown

# 第 16~25 秒
pidstat -u 1 3             # per-process CPU
pidstat -d 1 3             # per-process IO

# 第 26~35 秒
iostat -xzm 1 3            # disk IOPS & latency
free -h -w               # memory pressure

# 第 36~45 秒
sar -n DEV 1 3             # network throughput
sar -n TCP,ETCP 1 3          # TCP retransmits, listen drops

# 第 46~60 秒
top -bn1                # snapshot of top processes
ss -s                 # connection summary

这套命令序列能在 1 分钟内完成系统的全面体检,定位出瓶颈是 CPU、内存、IO 还是网络。

七、生产环境排查注意事项

不要在负载高时盲目重启——重启清除现场数据,根因可能永远丢失。除非系统完全无响应,否则优先排查而非重启。

先采集现场数据再操作:在执行 kill / rm / restart 之前,先把关键指标保存下来:

$ mkdir -p /tmp/debug_$(date +%s)
$ uptime > /tmp/debug_*/uptime
$ top -bn1 > /tmp/debug_*/top
$ vmstat 1 5 > /tmp/debug_*/vmstat
$ iostat -xdm 1 5 > /tmp/debug_*/iostat
$ ss -s > /tmp/debug_*/ss

判断依据要有数据支撑:不要说"我觉得是 IO 问题",而是"wa=53.8%、b=38、w_await=112ms,所以 IO 是瓶颈"。

灰度执行操作:如果有多个节点,先在一个节点上验证恢复方案,确认有效再推全量。

回滚方案要提前准备:修改配置前备份(cp /etc/logrotate.d/app /etc/logrotate.d/app.$(date +%F)),确保改错了能还原。

变更记录要完整:谁在什么时间执行了什么操作,影响范围是什么,要记录到故障复盘报告中。

八、总结

服务器负载过高的排查本质是找到瓶颈资源的过程。负载高 ≠ CPU 高,负载高可能来自:

I/O 瓶颈(最常见):wa 高、b 列高、iostat 显示磁盘饱和

CPU 瓶颈:us 高、r 列高、各核负载均衡

内存瓶颈:available 低、swap 活跃

网络瓶颈:重传率高、listen drops

排查流程可以固化为一个标准 SOP:

告警触发 → uptime 确认 → top 看 CPU 分布 → vmstat 看调度和阻塞 →
iostat/iotop 定位 IO → pidstat 确认进程 → lsof/straace 深挖根因 →
制定恢复方案 → 灰度执行 → 验证效果 → 根因整改

本次案例的核心教训是:日志轮转配置不当 + 日志级别失控是最容易被忽视的生产隐患。建议将 lsof 检查 deleted 文件作为新服务器上线检查清单中的一项,同时规范日志级别变更流程。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 负载
    +关注

    关注

    2

    文章

    677

    浏览量

    36729
  • cpu
    cpu
    +关注

    关注

    68

    文章

    11343

    浏览量

    226043
  • 服务器
    +关注

    关注

    14

    文章

    10386

    浏览量

    91785

原文标题:一次线上服务器负载过高的完整排查过程

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    linux服务器和windows服务器

    和适用。 首先,Linux服务器是一种基于开源的操作系统,其内核是由许多个人和组织共同开发和维护的。它具有高度的稳定性和安全 。由于Linux操作
    发表于 02-22 15:46

    参数模块和属性约简的应用服务器优化方法

    ,优化比较漫长,缺少系统性和规律,很难快速的确定所需调节的关键参数.本文针对常用的应用服务器分析了其性能下降的原因,提出了调节参数模块化思想并结合属性约简算法对参数模块进行属性约简,从实践中定量
    发表于 04-24 09:43

    基于Java移动代理的Web服务器负载监控系统

    本文分析了现有C/S 模式下Web 服务器负载监控系统存在的缺陷,在此基础上,给出了一种基于Java 移动代理的Web 服务器负载监控
    发表于 09-16 10:17 23次下载

    Web服务器的网络负载均衡

    介绍了网络负载均衡的定义和总体指标。详细讨论了网络负载均衡技术的4种类型。针对不同Web服务器的架构,分析了服务器的吞吐量和网络延迟,其结论对于有效提高
    发表于 12-25 16:25 26次下载

    什么是服务器网络负载均衡

    什么是服务器网络负载均衡 什么是负载均衡?
    发表于 01-11 10:58 2001次阅读

    负载均衡服务器有哪些

    负载均衡服务器是进行负载分配的服务器。通过负载均衡服务器,将
    发表于 12-21 10:02 1430次阅读
    <b class='flag-5'>负载</b>均衡<b class='flag-5'>服务器</b>有哪些

    Java服务器内存和CPU占用过高的原因

    造成服务器内存占用过高只有两种情况:内存溢出或内存泄漏
    的头像 发表于 03-21 15:50 2.3w次阅读

    服务器负载均衡有几种类型,做负载均衡好在哪

    对于服务器负载均衡可能很多朋友并不了解是什么,服务器负载均衡的简单理解就是指对系统中的负载情况进
    的头像 发表于 09-02 17:57 4262次阅读

    Linux服务器常见的网络故障排查方法

    日常工作中我们有时会遇到服务器网络不通问题,导致服务器无法正常运行。要想解决服务器网络故障问题,通常要先进行网络故障排查,这里以Linux服务器
    的头像 发表于 04-14 15:47 4104次阅读

    分布式节点服务器是什么?

    分布式节点服务器是一种将多个服务器分布式连接、协同工作,以实现负载均衡、提高系统性能和可靠、提供高可用
    的头像 发表于 01-12 15:04 1716次阅读
    分布式节点<b class='flag-5'>服务器</b>是什么?

    服务器入侵现象、排查和处理步骤

    近期有一个朋友的服务器(自己做了网站)好像遭遇了入侵,具体现象是: 服务器 CPU 资源长期 100%,负载较高。 服务器上面的服务不能正常
    发表于 03-22 10:56 1810次阅读
    <b class='flag-5'>服务器</b>入侵现象、<b class='flag-5'>排查</b>和处理步骤

    Linux服务器性能查看方法

    Linux服务器性能查看是系统管理员和开发人员在日常工作中经常需要进行的任务,以确保系统稳定运行并优化资源使用。以下将详细介绍多种Linux服务器性能查看的
    的头像 发表于 09-02 11:15 2841次阅读

    负载均衡服务器服务器如何连接?

    负载均衡服务器服务器如何连接?负载均衡服务器服务器可通过多种方式连接,包括直接连接、交换机连
    的头像 发表于 12-09 13:41 1104次阅读

    服务器怎么做负载均衡?

    增减服务器数量。健康检查定期监测服务器状态,故障时自动转移流量。跨区域部署提高可靠和访问速度,优化用户体验并增强抗灾能力。以下是 UU云 小编对这些技术的相关介绍: 分配策略 轮询:轮询是最基础的分配
    的头像 发表于 12-24 10:40 901次阅读

    服务器电源故障原因有哪些,服务器电源故障判断方法

    服务器作为现代数据中心的核心组件,其稳定性和可靠至关重要。电源作为服务器的“心脏”,其故障可能导致整个系统停机,严重影响业务的连续和数据
    的头像 发表于 01-30 14:26 3630次阅读