Linux 服务器响应慢的常见原因

Linux 服务器响应慢的常见原因

服务器“响应慢”是一个表象,背后往往是多个资源竞争、调度延迟、阻塞等待、队列积压或软硬件协同失效共同作用的结果。下面列出的 12 类原因,按照真实生产环境中出现频率从高到低排序,每一项都附上更深一层的技术机制解释、内核关键指标、典型误判点,以及最快定位的 1–2 个命令或观察点。

1. 磁盘 IO 等待(出现频率最高,约 40–55%)

内核机制 进程发起 read/write → VFS → page cache miss → 提交 bio 到 block layer → 进入 request queue → 调度器(mq-deadline / kyber / bfq / none) → 驱动层(nvme / scsi / virtio_blk) → 实际硬件完成 → 中断返回 → 唤醒等待进程。 任何一层延迟累积都会导致 iowait 升高,进程进入 D 状态(不可中断睡眠),从而推高 load average。

最典型表现

  • iowait 持续 > 20–40%,甚至 60–80%
  • iostat -x:%util 接近 100%,await 显著高于 svctm(说明队列长度很长)
  • vmstat:wa 高,b(不可中断睡眠进程数)持续 > 0

常见子场景

  • MySQL/PostgreSQL 随机读(索引扫描未命中、表扫描、sort / join 溢出到磁盘)
  • 日志类写入(nginx access/error、应用 debug 日志、数据库 binlog/wal 同步刷盘)
  • 大量小文件元数据操作(dentry/inode 缓存命中率低)

最快定位

Bash
iostat -xmdz 1 5                  # %util、await、r/s、w/s、rMB/s、wMB/s
iotop -o -P                       # 实时看哪个进程在产生大量读写
vmstat 1 5                        # wa 和 b 列

2. 数据库慢查询 / 锁等待

内核 + 应用层机制 SQL 执行 → 存储引擎层(InnoDB/MyRocks) → 加锁(行锁 / 间隙锁 / 意向锁) → 等待锁 → 进入 futex 等待 → 线程阻塞 → CPU 使用率反而下降,但 load 升高。

最典型表现

  • 部分接口延迟突然跳高(P99/P999 拉长),其他接口正常
  • 数据库进程 CPU 不高,但线程数 / 连接数高
  • show processlist 看到大量 “Waiting for table metadata lock” / “Waiting for table flush” / “Sending data”

最快定位

Bash
# MySQL / MariaDB
mysql -e "SHOW PROCESSLIST" | grep -v Sleep | grep -v system | head -20
mysql -e "SHOW ENGINE INNODB STATUS\G" | grep -A 20 "LATEST DETECTED DEADLOCK"

# PostgreSQL
SELECT * FROM pg_stat_activity WHERE state = 'active' AND wait_event IS NOT NULL;

3. CPU 计算密集

机制 大量用户态计算(us 高)或内核态计算(sy 高) → 运行队列长度(runq-sz)快速累积 → 新请求调度延迟增加 → 整体响应时间拉长。

最典型表现

  • us + sy 持续 > 80–90%,idle < 10–20%
  • vmstat r 列持续 > 核数 × 1.5–3
  • mpstat -P ALL 看到单核或少数核 100%,其他核空闲(热核问题)

最快定位

Bash
mpstat -P ALL 1 5
pidstat -u 1 5 | sort -k 8 -nr | head -15
perf top -K  # 或 perf record -F 99 -p PID -g -- sleep 30 后生成火焰图

4. 内存压力导致的 swap / 回收抖动

机制 kswapd / kcompactd 被频繁唤醒 → 直接回收 / 异步回收 → 页面偷取(steal) → 进程被短暂阻塞 → 延迟抖动。 极端情况下触发 OOM killer → 进程被杀 → 服务中断。

最典型表现

  • free -wh 的 available < 总内存 10–15% 且持续下降
  • vmstat si/so 非零且波动大
  • journalctl -k 出现 “kswapd0” CPU 占用高 或 “oom-kill”

最快定位

Bash
free -wh
vmstat 1 5                         # si/so 列
watch -n 2 'grep -E "Dirty|Writeback|AnonPages" /proc/meminfo'

5–12 简要高光

  1. 应用层 GC / 线程池耗尽 → Java Full GC 暂停、Go GC STW、Node event loop 阻塞 → jstat -gcutil、jcmd GC.heap_summary、线程 dump 看 BLOCKED / WAITING
  2. 网络拥塞 / 重传 / 丢包 → TCP 重传率 > 1–5%、listen queue overflow → ss -s、sar -n DEV 1 5、tcpdump 看 SYN/ACK 重传
  3. TIME_WAIT / 连接堆积 → net.ipv4.tcp_tw_reuse / tcp_fin_timeout 未优化 → ss -s 中 TIME_WAIT 几万以上
  4. 上下文切换 / 锁竞争 → cs > 20k–100k/s、大量 futex 等待 → pidstat -w、strace -c -p PID、perf record -e syscalls:sys_enter_futex
  5. 虚拟化 steal time → mpstat st > 5–15% → 云厂商超卖 / noisy neighbor
  6. 日志狂写挤占 IO → nginx / 应用日志未切割、debug 级别 → du -sh /var/log/*、iotop 看写进程
  7. DNS 解析慢 → resolv.conf 配置错误、上游 DNS 超时 → time dig +short api.example.com、resolvectl status
  8. 内核参数不当 → somaxconn / net.core.somaxconn / tcp_max_syn_backlog 过小 → ss -ltn state syn-recv | wc -l、netstat -s | grep overflow

生产环境 60 秒快速画像模板

text
load: 28.5 32.1 29.8(8核)  
top: wa 35%,us+sy 28%,id 32%,st 5%  
iostat: %util 92%,await 42ms,r/s 1800,w/s 450  
free: available 1.2G / 总 32G  
vmstat: r 18,b 12,cs 32000/s  
初步判断:磁盘 IO 饱和为主,辅以少量计算压力

可以分享你遇到的问题,描述一下具体表现是什么,我们可以共同来探讨。欢迎留言!
Telegram
Telegram@IDCSELL