Linux 复杂系统故障的拆解思路

2次阅读

系统级故障排查应优先使用dmesg和journalctl -b:dmesg提供内核环形缓冲区原始消息,journalctl -b覆盖从init到服务启动的完整日志链,二者可发现磁盘I/O卡死、驱动加载失败等底层问题。

Linux 复杂系统故障的拆解思路

dmesgjournalctl -b 开始,而不是直接查应用日志

系统级故障往往不是应用报错导致的,而是底层资源或驱动先出问题。比如磁盘 I/O 卡死、内核模块加载失败、电源管理异常——这些在应用日志里根本不会体现。dmesg 能看到内核 ring buffer 的第一手消息,journalctl -b 则覆盖了从 init 启动到各服务拉起的完整链条。

实操建议:

  • 优先运行 dmesg -T | tail -50(带时间戳,看最近 50 行),注意 Hardware ErrorWARNINGunable to handle kernel NULL pointer dereference 这类关键词
  • journalctl -b -p 3 只看 error 级别日志;若怀疑是某次重启后变差,用 journalctl -b -1 查上一次启动
  • 别跳过 journalctl -u systemd-udevdjournalctl -u systemd-journald——udev 规则错配、journald 自身卡住都会导致日志“消失”或延迟

strace 抓住“卡住但不报错”的进程

很多故障表现为服务响应慢、连接超时、命令 hang 住,但 ps aux 显示进程还在 running 状态。这时候 strace 是最直接的诊断工具,它能告诉你进程到底卡在哪条系统调用上。

常见错误现象:

  • http 服务突然大量 502,curl -v 却显示 TCP 连接成功但无响应 → 很可能是 accept()read() 阻塞
  • ls /mnt/nfs 卡住 → strace ls /mnt/nfs 通常会停在 stat()getdents64(),指向 NFS server 不可达或防火墙拦截了 portmap
  • 数据库客户端连不上,netstat -tnp 看不到连接 → strace -e trace=connect,socket,getaddrinfo psql ... 能确认是 DNS 解析失败还是 connect 被拒绝

注意:strace -p PID 对生产环境负载敏感,避免长时间挂载;更轻量的方式是加 -e trace=%network-e trace=epoll_wait,select 缩小范围。

lsofss 联合排查资源耗尽型故障

文件描述符、socket 连接数、内存映射页这些资源不是“用完才报错”,而是先行为异常:进程 fork 失败、open() 返回 EMFILE、TCP 连接积在 TIME_WAITSYN_RECV。单靠 freedf 完全看不出问题。

实操建议:

  • 查 fd 泄漏:lsof -n -p PID | wc -l 对比 cat /proc/PID/limits | grep "Max open files"
  • 查连接状态分布:ss -s 给出全局统计;ss -tan state time-wait | wc -l 看 TIME_WAIT 数量是否远超正常(如 >65535)
  • 查谁占着端口但没进程名:ss -tulpn | grep ':80',如果 pid/program 列为空,说明 socket 被内核保留(如 SO_REUSEPORT 场景)或权限不足无法读取
  • 注意 lsof +D /path 在大目录下极慢,等价但更快的是 find /path -xdev -type f -links +1 2>/dev/null | head -20(找硬链接异常)

别信 top 的 CPU%,用 perf toppidstat -w 看真实瓶颈

top 显示 CPU 使用率高,不代表程序逻辑有问题——可能只是频繁上下文切换、缺页中断、锁竞争或软中断(softirq)占满一个核。这种情况下优化代码毫无意义,得调内核参数或改硬件中断亲和性。

使用场景与差异:

  • perf top -p PID 能定位到具体函数或指令热点(比如 __do_softirq 占 90%),说明网卡收包处理压垮了 CPU
  • pidstat -w 1 关注 cswch/s(每秒自愿上下文切换)和 nvcswch/s(非自愿)。若后者远高于前者,大概率是锁争用或 CPU 时间片被抢
  • cat /proc/interrupts 配合 watch -n1 'cat /proc/interrupts | grep eth0',观察某网卡中断是否集中在单个 CPU 上(导致该核 100%,其他核空闲)
  • 注意 perf 默认采样频率是 4000Hz,生产环境建议降为 perf top -F 99 避免干扰,且需确保 /proc/sys/kernel/perf_event_paranoid ≤ 2

复杂点在于:很多故障是多个层叠加的结果——比如 NFS 挂载点卡住,既可能源于远端存储响应慢(strace 显示 read() 阻塞),也可能是本地 TCP 窗口缩为 0(ss -iwscalercv_space),还可能是内核 NFS client bug 导致重传逻辑异常。拆解时必须一层层剥,不能只盯最后一行错误。

text=ZqhQzanResources