跳到主要内容

🔍 故障排查与性能优化

开发环境出问题了?服务跑不动了?本章教你系统化排查的思路和工具。

排查哲学

出问题了,不要瞎猜!按这个顺序:

  1. 看日志(错误信息最直接)
  2. 看资源(CPU/内存/磁盘是否耗尽)
  3. 看网络(端口/防火墙/DNS 是否正常)
  4. 二分定位(最近改了什么?回滚试试?)

📜 日志分析技巧

高效 grep 过滤

# 查找错误(不区分大小写)
grep -i "error\|exception\|fatal" /var/log/app.log

# 显示上下文(错误前后 5 行)
grep -i "error" -A 5 -B 5 /var/log/app.log

# 按时间过滤(今天)
grep "$(date '+%Y-%m-%d')" /var/log/app.log

# 排除噪音(不含 "health check")
grep "error" /var/log/app.log | grep -v "health check"

# 统计错误数量(按小时)
grep "ERROR" /var/log/app.log | awk '{print $1, $2}' | cut -d: -f1-2 | sort | uniq -c

journalctl 高级过滤

# 查看某个服务的错误日志
sudo journalctl -u nginx --priority=err..alert

# 按时间过滤
sudo journalctl --since "2026-05-31 08:00:00" --until "2026-05-31 18:00:00"

# 实时追踪(生产环境排障神器)
sudo journalctl -u myapp -f

# 导出日志(发给同事分析)
sudo journalctl -u myapp --since "1 hour ago" > myapp-debug.log

多文件联合分析

# 同时看 nginx 访问日志和错误日志
tail -f /var/log/nginx/access.log /var/log/nginx/error.log

# 用 less 多文件翻页
less /var/log/syslog /var/log/auth.log
# 在 less 里按 :n 下一个文件,:p 上一个文件

# 多服务日志合并时间线
sudo journalctl -u nginx -u myapp --since "10 min ago" --no-pager

📊 性能监控工具

top / htop — CPU 和内存实时

top 输出解读:
top - 02:15:30 up 10 days, 3:22, 2 users, load average: 0.52, 0.38, 0.25
↑↑↑↑
CPU 负载(1/5/15 分钟平均)
1.0 = 1 核满载,4 核=4.0
指标含义正常值
load averageCPU 队列长度< CPU 核心数
%Cpu(s): us用户态 CPU 使用率< 70%
%Cpu(s): sy内核态 CPU 使用率< 30%
%Cpu(s): waI/O 等待(磁盘慢)< 10%
KiB Mem : used已用内存不要 100%(有 cache 正常)

iostat — 磁盘 I/O 分析

# 安装(sysstat 包)
sudo apt install sysstat

# 每 2 秒刷新一次磁盘 I/O
iostat -x 2

# 输出解读:
# %util = 磁盘繁忙百分比(> 80% 说明磁盘是瓶颈)
# await = I/O 等待时间(ms)(> 100ms 很慢)

free — 内存分析

free -h
# 输出解读:
# total — 总内存
# used — 已用(含 cache/buffer,正常!)
# free — 完全空闲(太小没关系)
# available — 可用(这个最重要!> 20% 总内存才健康)

ss / netstat — 网络连接分析

# 查看所有 TCP 连接
ss -tan

# 统计连接状态数量(排查 TIME_WAIT 堆积)
ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn

# 查看监听端口
ss -tulnp

# 查看某个进程打开的连接数(排查 fd 耗尽)
ls -la /proc/<PID>/fd | wc -l

🚨 常见故障场景

场景 1:服务起不来

排查流程(系统化):
1. 看状态 → systemctl status myapp
2. 看日志 → journalctl -u myapp -n 50
3. 检查配置 → myapp --check-config
4. 检查端口 → ss -tulnp | grep 3000
5. 检查依赖 → ping db-host / nc -zv db-host 5432
6. 检查权限 → ls -la /var/log/myapp.log
7. 检查磁盘空间 → df -h

场景 2:服务响应慢

排查流程:
1. 看负载 → top(CPU 高?还是 I/O 等待高?)
2. 看内存 → free -h(OOM 了?Swap 在用了?)
3. 看磁盘 → iostat -x 2(磁盘 100% util?)
4. 看网络 → ss -tan | grep ESTAB | wc -l(连接数爆炸?)
5. 看进程 → htop(哪个进程吃资源?)
6. 看日志 → grep "ERROR\|WARN" /var/log/myapp.log

场景 3:磁盘满了

# 1. 查看哪个分区满了
df -h

# 2. 找大文件(从根目录开始查)
sudo du -sh /* 2>/dev/null | sort -rh | head -20
# 逐级深入
sudo du -sh /var/* 2>/dev/null | sort -rh | head -20

# 3. 找大文件(> 100MB)
sudo find / -type f -size +100M 2>/dev/null | xargs ls -lh

# 4. 清理 Docker(开发环境最常见元凶)
docker system prune -a --volumes -f

# 5. 清理日志
sudo truncate -s 0 /var/log/syslog # 清空日志文件(不删文件)
sudo journalctl --vacuum-size=500M # journal 日志只保留 500MB

场景 4:内存泄漏(OOM Killer)

# 1. 查看 OOM Killer 日志
dmesg | grep -i "killed process"

# 2. 查看进程内存使用 TOP 10
ps aux --sort=-%mem | head -11

# 3. 查看系统内存
free -h
cat /proc/meminfo | grep -E "MemTotal|MemFree|MemAvailable|Cached"

# 4. 临时解决:重启内存泄漏的服务
sudo systemctl restart leaky-service

# 5. 根本解决:用 valgrind 或 gdb 定位泄漏(C/C++)
valgrind --leak-check=full ./myprogram

场景 5:网络不通

排查流程:
1. ping 目标 → ping 8.8.8.8(基础连通性)
2. DNS 解析 → dig example.com(DNS 是否正常?)
3. 端口是否开启 → nc -zv example.com 443(目标端口是否开?)
4. 本地防火墙 → sudo ufw status
5. 云安全组 → 去云控制台检查
6. 路由 → traceroute example.com(哪一跳断了?)

🏎️ 性能优化思路

CPU 优化

CPU 瓶颈排查:
1. top / htop 找到高 CPU 进程
2. perf top -p <PID> 看热点函数(需要安装 linux-tools)
3. 用 profiler 工具(如 py-spy for Python, node --prof for Node.js)
4. 优化算法 / 加缓存 / 异步化

内存优化

内存瓶颈排查:
1. free -h 看 available 是否 < 10%
2. ps aux --sort=-%mem 找元凶
3. 用 valgrind / AddressSanitizer 查 C/C++ 泄漏
4. 用语言专用工具(Python: tracemalloc, Node.js: heapdump)

磁盘 I/O 优化

I/O 瓶颈排查:
1. iostat -x 2 看 %util 和 await
2. iotop 看哪个进程在大量 I/O
3. 优化方案:
- 加内存(cache 更多数据)
- 换 SSD(延迟从 10ms → 0.1ms)
- 优化数据库查询(加索引)
- 用异步写(write-back cache)

网络优化

网络瓶颈排查:
1. ss -tan 看连接状态(大量 TIME_WAIT?)
2. ip -s link 看网卡丢包
3. 优化方案:
- 调大 TCP backlog(net.core.somaxconn)
- 启用 TCP BBR 拥塞控制
- 用 CDN 或负载均衡
- 压缩传输数据(gzip/brotli)

📋 排障检查清单

宕机/无响应检查清单

□ 服务器是否在线?(ping / SSH)□ CPU 是否 100%?(top)□ 内存是否耗尽?(free -h)□ 磁盘是否满了?(df -h)□ 进程是否崩溃?(systemctl status / journalctl)□ 端口是否监听?(ss -tulnp)□ 防火墙是否放行?(sudo ufw status)□ DNS 是否解析?(dig)□ 日志有没有错误?(journalctl -p err)□ 最近有没有变更?(git log --since="1 day ago")□ 依赖服务是否正常?(数据库/Redis/消息队列)

📚 下一步