第 100 课 - 实战:系统故障排查方法论
学习目标
完成本课学习后,你将能够:
- 建立系统性排查思维:掌握“分层、分模块、由外而内、由浅入深”的故障排查核心逻辑。
- 掌握关键工具链:熟练组合使用
systemctl,journalctl,top,ss,dmesg,strace等命令快速定位问题。 - 设计并执行排查方案:针对常见的服务器故障(如服务不可用、系统卡顿、网络中断),能设计一套标准、可重复的排查流程。
- 快速恢复业务:在定位问题的同时,掌握快速恢复服务、保障业务连续性的关键操作。
核心概念
系统故障排查并非凭感觉猜测,而是基于证据的科学侦探过程。其核心思想是 “假设 -> 验证 -> 修正” 的循环。
1. 排查金字塔模型
我们可以将系统问题想象成一个金字塔,从顶向下排查:
- 顶层:用户影响 - 服务不可用?响应慢?
- 第二层:应用服务 - Web 服务、数据库进程是否正常运行?
- 第三层:系统资源 - CPU、内存、磁盘 I/O、网络是否成为瓶颈?
- 第四层:内核与驱动 - 系统日志有无报错?
- 底层:硬件 - 硬盘、网卡、内存是否损坏? 原则:从用户感受最直接的顶层开始,逐步向下深入。
2. 核心工具链串联
单个工具的信息是碎片化的,组合使用才能看清全貌:
- 宏观监控:
top/htop(CPU/内存),vmstat 1(综合),iostat -x 1(磁盘),ss -tnap(网络连接)。 - 服务状态:
systemctl status <service>查看进程状态、主进程PID及最近日志。 - 系统日志:
journalctl -u <service> --since "10 minutes ago"或直接查看/var/log/messages。 - 深入追踪:
strace -p <PID>跟踪进程系统调用,tcpdump抓包分析网络。 - 安全与权限:
auditd日志,lsof -p <PID>查看进程打开的文件。
3. “OSI 七层”式排查流程(Linux简化版)
当服务完全无法访问时,可参照此流程:
- 物理/链路层:
ping网关和外部IP,检查网卡状态 (ip link)。 - 网络层:
traceroute查看路由,ss -tnap检查目标端口是否在监听。 - 进程/服务层:
systemctl status,ps aux | grep <service>。 - 应用/权限层:检查配置文件 (
/etc/nginx/nginx.conf),查看应用自身日志 (/var/log/nginx/error.log),检查SELinux/AppArmor (getenforce)。
代码示例
以下是一个综合性的故障模拟与排查脚本。我们将模拟一个常见的场景:Nginx 服务因资源耗尽而停止响应。
#!/bin/bash
# 故障模拟脚本 - 请勿在生产环境运行!
# 运行前请确保已安装 nginx, stress 工具: `sudo apt install stress` 或 `sudo yum install stress`
echo "正在模拟系统故障..."
# 1. 模拟内存泄漏,导致内存耗尽
stress --vm 2 --vm-bytes 256M --timeout 30s &
echo "1. 已启动内存压力测试。"
# 2. 模拟磁盘空间被占满
dd if=/dev/zero of=/tmp/fill_disk.img bs=1M count=100 &
echo "2. 已启动磁盘填充进程。"
# 3. 模拟Nginx配置错误并重启
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
sudo bash -c 'echo "invalid_syntax" >> /etc/nginx/nginx.conf'
sudo systemctl restart nginx
echo "3. 已注入Nginx配置错误并尝试重启。"
echo "故障模拟完成,请开始排查!"
排查步骤演示:
# 步骤1:快速感知 - 用户反馈“网站打不开”
curl -I localhost # 预期结果:连接失败或返回5xx错误
# 步骤2:服务层检查 - Nginx服务状态
sudo systemctl status nginx
# 可能输出:Active: failed (Result: exit-code)
# 步骤3:深入查看服务日志
sudo journalctl -u nginx --no-pager -n 20
# 可能输出:nginx: [emerg] unknown directive "invalid_syntax" in /etc/nginx/nginx.conf:23
# 步骤4:检查系统资源压力
free -h # 查看内存,可能显示可用内存极低
df -h /tmp # 查看磁盘空间,可能显示/tmp分区100%
top -bn1 | head -20 # 查看CPU负载及内存使用高的进程
# 步骤5:清理与恢复
sudo cp /etc/nginx/nginx.conf.bak /etc/nginx/nginx.conf # 恢复配置
sudo systemctl restart nginx
# 清理压力测试进程和文件
pkill stress
rm /tmp/fill_disk.img
# 再次检查服务
curl -I localhost # 预期结果:HTTP/1.1 200 OK
实践练习
练习一:基础排查(进程故障)
- 模拟:运行
tail -f /dev/null &,然后使用kill命令发送错误信号(如 SIGKILL)杀死它。 - 要求:使用
ps,journalctl,dmesg | tail命令,找到进程异常终止的线索。 - 预期输出:在
dmesg或journalctl中找到类似tail[1234]: segfault at ...或tail: terminated的记录。
练习二:综合排查(系统卡顿)
- 模拟:同时打开两个终端。
- 终端1:运行
stress --cpu 4 --timeout 60s模拟CPU打满。 - 终端2:运行
stress --io 4 --timeout 60s模拟磁盘I/O压力。
- 终端1:运行
- 要求:在第三个终端中,仅使用命令行工具,依次执行以下操作:
- 观察整体负载 (
uptime)。 - 定位消耗资源最高的进程 (
top,htop)。 - 判断瓶颈是CPU还是I/O (
vmstat 1,iostat -x 1)。
- 观察整体负载 (
- 预期输出:
top命令中能清晰看到stress进程,并能根据wa(I/O等待) 和%Cpu(s)的值判断主要瓶颈。
练习三:网络服务排查
- 模拟:启动一个简单的HTTP服务 (
python3 -m http.server 8080 &),然后用firewalld或iptables屏蔽该端口。 - 要求:设计一个排查流程,依次检查:本机端口监听、本地回环连接、防火墙规则。
- 预期输出:使用
ss -tnlp | grep 8080确认服务监听,curl localhost:8080成功,curl <服务器公网IP>:8080失败,最后通过sudo iptables -L -n或sudo firewall-cmd --list-ports找到阻塞规则。
常见错误
- 缺乏全局观,直接“钻牛角尖”:一看到错误日志就急于修改,没有先观察系统整体状态(负载、资源),可能忽略了真正的根本原因(例如,是内存不足导致服务被OOM Killer杀死,而非服务自身bug)。
- 过度依赖单一工具:只看
top就认为 CPU 高,没有结合perf或strace看是哪个函数/系统调用导致的,无法定位到代码级别。 - 直接重启:重启可能快速恢复服务,但会丢失所有现场信息。正确的做法是:在重启前,尽可能收集信息(
ps auxf,journalctl -xe,top -b -n 1 > /tmp/top.txt,/proc信息等)。 - 忽视安全上下文:服务启动失败,除了检查日志和配置,还要检查文件权限、SELinux/AppArmor 的
denial日志 (audit2why,ausearch)。 - 不沟通、不记录:故障排查是团队协作,及时通报进展和发现。事后必须编写故障报告(Root Cause Analysis),记录时间线、现象、原因、解决方案和预防措施。
小结
- 方法论是核心:掌握 “监控感知 -> 分层定位 -> 工具验证 -> 清理恢复 -> 复盘预防” 的闭环思维。
- 工具是武器:熟练掌握
systemctl,journalctl,top,ss,strace,tcpdump等工具的组合使用,它们是你侦查现场的“眼睛”和“耳朵”。 - 证据驱动:每一个判断都应基于命令输出的日志、状态信息,而非猜测。
- 业务优先:在排查复杂问题时,首要目标是恢复业务(如切换主备、重启服务),其次是保留现场进行根因分析。
- 持续学习:系统故障千奇百怪,持续积累案例,学习
perf,bpftrace等高级工具,能让你成为一名更出色的“系统侦探”。
恭喜你完成本系列课程的最后一课!系统故障排查是一项需要理论结合大量实践的技能。记住,最优秀的运维工程师不是从不遇到故障,而是能在故障发生时,冷静、快速、准确地定位并解决问题。带着本课的方法论,去实践,去总结,你将无惧任何挑战。
练习编辑器
rust
Loading...