HiHuo
首页
博客
手册
工具
关于
首页
博客
手册
工具
关于
  • Linux 系统工具完全指南

    • Linux 系统工具完全指南
    • 高频工具 - 每天使用
    • 中频工具 - 每周使用
    • 低频但重要的工具
    • 开发环境工具
    • 故障排查与诊断

故障排查与诊断

线上出问题时的救命工具和方法论


一、故障排查方法论

1.1 排查思路

遇到问题时,按照以下顺序排查:

1. 确认现象
   └── 什么症状?什么时候开始?影响范围?

2. 收集信息
   ├── 系统资源:CPU、内存、磁盘、网络
   ├── 日志信息:系统日志、应用日志
   └── 变更记录:最近有什么变更?

3. 定位问题
   ├── 是否资源瓶颈?
   ├── 是否配置错误?
   ├── 是否代码问题?
   └── 是否外部依赖问题?

4. 解决问题
   ├── 临时方案:重启服务、扩容、降级
   └── 根本方案:修复代码、优化配置

5. 复盘总结
   └── 问题原因、解决过程、预防措施

1.2 快速检查清单

# 1. 系统负载
uptime
top -bn1 | head -20

# 2. 内存使用
free -h
vmstat 1 5

# 3. 磁盘使用
df -h
iostat -x 1 3

# 4. 网络状态
netstat -tunlp
ss -s

# 5. 最近日志
tail -100 /var/log/syslog
journalctl --since "10 minutes ago"

# 6. 进程状态
ps aux --sort=-%cpu | head
ps aux --sort=-%mem | head

# 7. 最近登录
last -10

# 8. 系统事件
dmesg | tail -50

二、系统诊断

2.1 dmesg - 内核消息

dmesg 显示内核环形缓冲区的消息,对于排查硬件和驱动问题非常有用:

# 查看所有消息
dmesg
dmesg | less

# 最近消息
dmesg | tail -50
dmesg -T | tail -50              # 显示时间戳

# 按级别过滤
dmesg --level=err                # 错误
dmesg --level=warn               # 警告
dmesg --level=err,warn           # 错误和警告

# 清除消息(需要 root)
sudo dmesg -c

# 实时监控
dmesg -w                         # 类似 tail -f
dmesg -wT                        # 带时间戳

# 常见问题关键字搜索
dmesg | grep -i error
dmesg | grep -i fail
dmesg | grep -i "out of memory"
dmesg | grep -i "killed process"  # OOM Killer
dmesg | grep -i "I/O error"       # 磁盘错误

常见问题示例

# 1. OOM (Out of Memory) 问题
dmesg | grep -i "out of memory"
dmesg | grep -i "oom"

# 2. 磁盘错误
dmesg | grep -i "I/O error"
dmesg | grep -i "EXT4-fs error"

# 3. 网卡问题
dmesg | grep -i eth0
dmesg | grep -i "link down"

# 4. USB 设备
dmesg | grep -i usb

# 5. CPU 问题
dmesg | grep -i "CPU"
dmesg | grep -i "temperature"

2.2 系统日志分析

# Ubuntu/Debian 系统日志
tail -f /var/log/syslog
grep -i error /var/log/syslog

# CentOS/RHEL 系统日志
tail -f /var/log/messages

# 认证日志(SSH 登录失败等)
tail /var/log/auth.log           # Ubuntu
tail /var/log/secure             # CentOS
grep "Failed password" /var/log/auth.log

# 使用 journalctl
journalctl -p err -b             # 本次启动的错误
journalctl -p err --since today
journalctl -u nginx -p err
journalctl --since "2025-01-20 10:00" --until "2025-01-20 11:00"

2.3 系统资源总览

# 综合查看
htop                             # 推荐
top

# 系统概况
vmstat 1 10
# 输出解释:
# r: 运行队列长度(>CPU数则繁忙)
# b: 阻塞进程数
# si/so: swap in/out(>0 说明内存不足)
# bi/bo: 块设备 I/O
# us/sy/id/wa: CPU 用户态/内核态/空闲/IO等待

# 资源使用概况脚本
echo "=== CPU ==="
top -bn1 | head -5
echo -e "\n=== Memory ==="
free -h
echo -e "\n=== Disk ==="
df -h | grep -v tmpfs
echo -e "\n=== Load ==="
uptime

三、CPU 诊断

3.1 CPU 使用率分析

# 查看 CPU 使用率
top -bn1 | head -20
mpstat 1 5                       # 每秒采样,共5次
mpstat -P ALL 1 5                # 每个 CPU

# CPU 使用率高的进程
ps aux --sort=-%cpu | head -10

# 实时查看
top
# 按 P 键按 CPU 排序
# 按 1 键显示每个 CPU

3.2 CPU 负载分析

# 查看负载
uptime
cat /proc/loadavg

# 负载解读
# 三个数字分别是 1分钟、5分钟、15分钟平均负载
# 负载 = 正在运行 + 等待运行的进程数
# 单核 CPU:负载 1.0 = 100% 使用
# 4核 CPU:负载 4.0 = 100% 使用
# 负载 > CPU 核数 → 过载

# 查看 CPU 核数
nproc
grep -c processor /proc/cpuinfo

3.3 CPU 问题排查

# 1. 找到 CPU 高的进程
top -c                           # 显示完整命令

# 2. 查看进程详情
ps -ef | grep <pid>
cat /proc/<pid>/cmdline

# 3. 查看进程的线程
top -H -p <pid>
ps -T -p <pid>

# 4. 查看进程在做什么
strace -p <pid>                  # 系统调用
perf top -p <pid>                # 热点函数

# 5. 生成火焰图
perf record -g -p <pid>
perf script > out.perf
# 用 FlameGraph 工具生成火焰图

四、内存诊断

4.1 内存使用分析

# 查看内存使用
free -h
# 重要:看 available,而不是 free
# buff/cache 是可回收的

# 详细内存信息
cat /proc/meminfo
cat /proc/meminfo | grep -E "MemTotal|MemFree|MemAvailable|Buffers|Cached|SwapTotal|SwapFree"

# 内存使用趋势
vmstat 1 10
# 关注 si/so(swap in/out),>0 说明内存紧张

# 内存使用高的进程
ps aux --sort=-%mem | head -10

4.2 内存泄漏排查

# 查看进程内存使用
ps aux --sort=-%mem | head -10
top -o %MEM

# 查看进程内存详情
pmap -x <pid>
cat /proc/<pid>/status | grep -E "VmPeak|VmRSS|VmSwap"

# 内存使用随时间变化
while true; do
    ps -o pid,rss,cmd -p <pid>
    sleep 60
done

# 使用 valgrind 检测(需要重启进程)
valgrind --leak-check=full ./program

4.3 OOM Killer 排查

# 查看 OOM 日志
dmesg | grep -i "out of memory"
dmesg | grep -i "killed process"
journalctl -k | grep -i "oom"

# 查看 OOM 分数
cat /proc/<pid>/oom_score
cat /proc/<pid>/oom_score_adj

# 设置进程 OOM 分数(-1000 到 1000)
echo -1000 | sudo tee /proc/<pid>/oom_score_adj  # 不容易被杀
echo 1000 | sudo tee /proc/<pid>/oom_score_adj   # 优先被杀

4.4 Swap 分析

# 查看 swap 使用
free -h
swapon --show
cat /proc/swaps

# 查看哪些进程使用 swap
for pid in /proc/[0-9]*; do
    awk '/VmSwap/{if($2>0)print "'$pid':",$0}' $pid/status 2>/dev/null
done | sort -k2 -nr | head

# 或使用 smem 工具
sudo apt install smem
smem -s swap -r | head

# swap 使用过高的解决方案
# 1. 增加物理内存
# 2. 优化应用内存使用
# 3. 调整 swappiness
sysctl vm.swappiness=10

五、磁盘诊断

5.1 磁盘空间分析

# 查看磁盘使用
df -h
df -h | grep -v tmpfs

# 查看 inode 使用
df -i

# 查找大目录
du -sh /*
du -sh /var/*
du -h --max-depth=1 / 2>/dev/null | sort -hr | head

# 查找大文件
find / -type f -size +100M 2>/dev/null | head
find / -type f -size +1G 2>/dev/null

# 使用 ncdu(推荐)
sudo apt install ncdu
ncdu /

5.2 磁盘 I/O 分析

# 查看磁盘 I/O
iostat -x 1 5
# 关键指标:
# %util: 设备繁忙程度(>70% 可能是瓶颈)
# await: I/O 等待时间(>100ms 较高)
# r/s, w/s: 每秒读写次数
# rkB/s, wkB/s: 每秒读写量

# 查看 I/O 高的进程
sudo iotop -o
sudo iotop -P                    # 显示进程而非线程

# 查看进程的 I/O 统计
cat /proc/<pid>/io

# 磁盘性能测试
# 写性能
dd if=/dev/zero of=testfile bs=1M count=1000 oflag=direct
# 读性能
dd if=testfile of=/dev/null bs=1M count=1000 iflag=direct
rm testfile

5.3 磁盘故障检测

# 查看磁盘健康状态(SMART)
sudo apt install smartmontools
sudo smartctl -H /dev/sda        # 健康状态
sudo smartctl -a /dev/sda        # 详细信息

# 检查文件系统
sudo fsck -n /dev/sda1           # 检查但不修复
# 注意:fsck 需要在卸载状态下运行

# 查看磁盘错误日志
dmesg | grep -i "I/O error"
dmesg | grep -i sda

# 坏块检测
sudo badblocks -v /dev/sda       # 警告:这很慢

5.4 清理磁盘空间

# 清理包管理器缓存
sudo apt clean                   # Debian/Ubuntu
sudo apt autoremove
sudo yum clean all               # CentOS/RHEL

# 清理日志
sudo journalctl --vacuum-time=7d
sudo journalctl --vacuum-size=500M

# 清理旧内核
sudo apt autoremove --purge      # Ubuntu
package-cleanup --oldkernels     # CentOS

# 查找并删除大日志
find /var/log -name "*.gz" -mtime +30 -delete
find /var/log -name "*.log.*" -mtime +30 -delete

# 清空大日志(不删除文件)
> /var/log/large.log

六、网络诊断

6.1 网络连通性

# 基本连通性
ping -c 4 target.com

# 路由追踪
traceroute target.com
tracepath target.com
mtr target.com                   # 更好的工具

# DNS 解析
dig target.com
nslookup target.com
host target.com

# DNS 解析问题排查
dig @8.8.8.8 target.com          # 使用 Google DNS
dig target.com +trace            # 追踪解析过程

6.2 端口和连接

# 查看监听端口
netstat -tunlp
ss -tunlp

# 查看特定端口
netstat -anp | grep :80
ss -anp | grep :80
lsof -i :80

# 查看连接状态
netstat -ant | awk '{print $6}' | sort | uniq -c
ss -s

# 连接状态详解
# ESTABLISHED: 已建立
# TIME_WAIT: 等待关闭(太多说明短连接多)
# CLOSE_WAIT: 等待关闭(太多说明程序没正确关闭连接)

# 查看特定状态的连接
ss -ant state time-wait
ss -ant state close-wait

# 查看连接到特定端口的 IP
netstat -ant | grep :80 | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head

6.3 网络流量分析

# 查看流量
iftop -i eth0
nload eth0

# 查看网络统计
netstat -s
ss -s

# 查看网络接口统计
ip -s link
cat /proc/net/dev

# 查看网络接口错误
ifconfig eth0 | grep -E "errors|dropped|overruns"

6.4 抓包分析

# tcpdump 基础
sudo tcpdump -i eth0
sudo tcpdump -i eth0 port 80
sudo tcpdump -i eth0 host 192.168.1.100

# 保存抓包
sudo tcpdump -i eth0 -w capture.pcap
sudo tcpdump -i eth0 -c 100 -w capture.pcap  # 抓100个包

# 读取抓包
tcpdump -r capture.pcap
tcpdump -r capture.pcap -A                   # ASCII 显示

# HTTP 请求分析
sudo tcpdump -i eth0 -A -s 0 'port 80 and tcp' | grep -E "GET|POST|Host:|HTTP/"

# 查看 TCP 握手
sudo tcpdump -i eth0 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0'

6.5 常见网络问题排查

# 1. 无法连接远程服务
ping target.com                  # 检查网络
telnet target.com 80             # 检查端口
curl -v target.com               # 检查 HTTP

# 2. DNS 解析慢
time dig target.com              # 检查解析时间
dig @8.8.8.8 target.com          # 换 DNS 测试

# 3. 连接超时
traceroute target.com            # 检查路由
mtr target.com                   # 检查丢包

# 4. 连接被拒绝
# 检查目标端口是否开放
# 检查防火墙规则
sudo iptables -L -n
sudo ufw status

# 5. 大量 TIME_WAIT
# 调整内核参数
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.tcp_fin_timeout=30

# 6. 带宽测试
iperf3 -s                        # 服务端
iperf3 -c server_ip              # 客户端

七、服务诊断

7.1 进程状态检查

# 查看服务状态
systemctl status nginx
systemctl status mysql

# 查看服务日志
journalctl -u nginx
journalctl -u nginx -f           # 实时
journalctl -u nginx --since "1 hour ago"

# 查看进程
ps aux | grep nginx
pgrep -a nginx

# 查看进程详情
ps -fp <pid>
cat /proc/<pid>/cmdline
cat /proc/<pid>/environ

# 查看进程打开的文件
lsof -p <pid>
ls -la /proc/<pid>/fd

# 查看进程网络连接
lsof -i -p <pid>
ss -p | grep <pid>

7.2 应用日志分析

# 查看应用日志
tail -f /var/log/nginx/error.log
tail -f /var/log/mysql/error.log

# 搜索错误
grep -i error /var/log/app/app.log
grep -i exception /var/log/app/app.log

# 统计错误数量
grep -c "ERROR" /var/log/app/app.log
grep "ERROR" /var/log/app/app.log | wc -l

# 按时间段分析
awk '$4 >= "[20/Jan/2025:10:00:00" && $4 <= "[20/Jan/2025:11:00:00"' access.log

# 分析访问日志
# 统计 IP 访问量
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head

# 统计 HTTP 状态码
awk '{print $9}' access.log | sort | uniq -c | sort -rn

# 统计请求路径
awk '{print $7}' access.log | sort | uniq -c | sort -rn | head

# 统计每秒请求数
awk '{print $4}' access.log | cut -d: -f2-4 | uniq -c | sort -rn | head

7.3 数据库诊断

# MySQL
mysql -e "SHOW PROCESSLIST"
mysql -e "SHOW STATUS LIKE '%connect%'"
mysql -e "SHOW STATUS LIKE '%thread%'"
mysql -e "SHOW ENGINE INNODB STATUS\G"

# 慢查询
mysql -e "SHOW VARIABLES LIKE 'slow_query%'"
mysql -e "SHOW VARIABLES LIKE 'long_query%'"

# PostgreSQL
psql -c "SELECT * FROM pg_stat_activity"
psql -c "SELECT * FROM pg_stat_database"

# Redis
redis-cli info
redis-cli info clients
redis-cli info memory
redis-cli slowlog get 10

八、综合排查场景

8.1 服务器响应慢

# 1. 检查系统负载
uptime
top -bn1 | head -20

# 2. 检查内存
free -h
vmstat 1 5

# 3. 检查磁盘 I/O
iostat -x 1 5

# 4. 检查网络
netstat -ant | wc -l
ss -s

# 5. 检查应用进程
ps aux --sort=-%cpu | head
ps aux --sort=-%mem | head

# 6. 检查日志
tail -100 /var/log/app/app.log | grep -i error

8.2 服务无法启动

# 1. 查看服务状态
systemctl status myapp

# 2. 查看详细日志
journalctl -u myapp -n 100

# 3. 检查配置文件
# 配置文件语法检查
nginx -t
apache2ctl configtest

# 4. 检查端口占用
netstat -tunlp | grep :80
lsof -i :80

# 5. 检查权限
ls -la /path/to/app
ls -la /var/log/app

# 6. 检查依赖
ldd /path/to/binary            # 检查动态库依赖

8.3 磁盘空间满

# 1. 查看磁盘使用
df -h

# 2. 查找大目录
du -h --max-depth=1 / 2>/dev/null | sort -hr | head

# 3. 查找大文件
find / -type f -size +100M 2>/dev/null

# 4. 查找被删除但占用空间的文件
lsof | grep deleted

# 5. 清理
# 清理日志
sudo journalctl --vacuum-time=3d
# 清理包缓存
sudo apt clean
# 清理旧日志
find /var/log -name "*.gz" -mtime +30 -delete

8.4 网络连接问题

# 1. 检查本地网络
ip addr
ip route

# 2. 检查 DNS
cat /etc/resolv.conf
dig google.com

# 3. 检查连通性
ping 8.8.8.8
ping google.com

# 4. 检查路由
traceroute google.com

# 5. 检查防火墙
sudo iptables -L -n
sudo ufw status

# 6. 检查端口
telnet target 80
nc -zv target 80

九、监控脚本示例

9.1 系统健康检查脚本

#!/bin/bash
# system-health-check.sh

echo "===== System Health Check ====="
echo "Time: $(date)"
echo

echo "=== System Info ==="
uname -a
echo

echo "=== Uptime ==="
uptime
echo

echo "=== CPU Usage (Top 5) ==="
ps aux --sort=-%cpu | head -6
echo

echo "=== Memory Usage ==="
free -h
echo

echo "=== Memory Usage (Top 5) ==="
ps aux --sort=-%mem | head -6
echo

echo "=== Disk Usage ==="
df -h | grep -v tmpfs
echo

echo "=== Network Connections ==="
ss -s
echo

echo "=== Recent Errors ==="
journalctl -p err --since "1 hour ago" | tail -20
echo

echo "=== Failed Services ==="
systemctl list-units --state=failed

9.2 磁盘监控脚本

#!/bin/bash
# disk-monitor.sh

THRESHOLD=80
EMAIL="admin@example.com"

df -h | grep -vE '^Filesystem|tmpfs' | while read line; do
    usage=$(echo $line | awk '{print $5}' | sed 's/%//')
    partition=$(echo $line | awk '{print $6}')

    if [ $usage -ge $THRESHOLD ]; then
        echo "Warning: $partition is ${usage}% full"
        # 发送邮件
        # echo "Disk space warning: $partition is ${usage}% full" | mail -s "Disk Alert" $EMAIL
    fi
done

9.3 服务监控脚本

#!/bin/bash
# service-monitor.sh

SERVICES="nginx mysql redis"

for service in $SERVICES; do
    if ! systemctl is-active --quiet $service; then
        echo "$(date): $service is not running, attempting restart..."
        systemctl restart $service

        if systemctl is-active --quiet $service; then
            echo "$(date): $service restarted successfully"
        else
            echo "$(date): Failed to restart $service"
            # 发送告警
        fi
    fi
done

十、故障排查工具速查表

问题类型常用命令
CPU 高top, ps aux --sort=-%cpu, perf top
内存高free -h, ps aux --sort=-%mem, vmstat
磁盘满df -h, du -sh, ncdu
磁盘 I/O 高iostat -x, iotop, pidstat -d
网络问题ping, traceroute, mtr, netstat, ss
进程问题ps, top, strace, lsof
服务问题systemctl status, journalctl -u
系统日志dmesg, journalctl, /var/log/
抓包分析tcpdump, wireshark, tshark

总结

故障排查是后端开发者必备的技能。记住以下要点:

  1. 保持冷静:先收集信息,再做判断
  2. 从简单到复杂:先检查最常见的问题
  3. 看日志:日志是最重要的信息来源
  4. 监控为先:有监控能更快发现问题
  5. 记录过程:为复盘和知识积累做准备

核心工具:

  • 系统:top, vmstat, dmesg, journalctl
  • 磁盘:df, du, iostat, iotop
  • 网络:netstat, ss, tcpdump, ping, traceroute
  • 进程:ps, strace, lsof

建议定期进行故障演练,熟悉这些工具的使用,这样在真正遇到问题时才能从容应对。

Prev
开发环境工具