🧩 第08章 · 故障排查综合
从现象到根因的一套思路
故障排查综合¶
这一章给出一套可以套用到绝大多数故障的排查方法论,并用这台服务器可能遇到的真实故障做例子:网站 502、服务起不来、数据库连接失败、磁盘撑爆。故障排查的本质是"分层定位 + 基于证据下判断",而不是瞎重启。
排查心法:先分层,再切分¶
原则:永远从"可观察到的事实"出发,顺着系统层级往下(或往上)推,每一层用一条命令验证,而不是猜。
一层层通常是这样:
用户/浏览器 → 域名解析(DNS) → 反向代理/负载均衡(nginx) → 应用服务(node) → 依赖(redis/mysql) → 资源(CPU/内存/磁盘) → 网络(防火墙/端口)
通用排查流程(四步)¶
① 出问题的具体表现是什么? 什么时间、什么入口、报什么错、影响多少人。先拿事实,不拿猜测。
② 是哪一层没通过? 用一条命令快速切分。例:网站打不开——
# 这域名解析正常吗
dig +short learn.bangdream.xyz
# 443 端口通吗("连接被拒" vs "超时" 结论不同)
nc -zv 2.25.183.241 443
# 本地到 443 的 HTTP 层通吗
curl -sSI https://learn.bangdream.xyz/ | head -3
# 是 nginx 的锅还是后端的锅
curl -sSI http://127.0.0.1:3000/ # 直接打后端,绕过 nginx
③ 缩小范围到单点。 如果直接打后端 3000 也不通,说明是应用或依赖问题;如果后端通、前面不通,是 nginx/网络层问题。
④ 找到根因并修复,再验证。 修完之后用命令复验,不要口头"应该好了"。
案例 1:站点返回 502 Bad Gateway¶
502 表示 nginx 收到了请求,但转发时(proxy_pass)后端没正常响应。常见于后端挂了/没监听。
# 1) 后端在监听吗
ss -tlnp | grep ':3000'
# 2) 后端进程活着吗
systemctl status bangdream
# 3) 后端日志
journalctl -u bangdream -n 30 -p err
# 4) 进程满血吗
ps aux | grep node | head
- 若
LISTEN 0.0.0.0:3000没有 → 服务没起,systemctl start bangdream并看为什么起不来。 - 若起起来又立刻退 → 看
journalctl里的报错(缺 env、端口被占、依赖 mysql 没起)。 - 若后端转圈 → 看是不是它对 mysql 的连接超时(参考案例 3)。
案例 2:服务一启动就退出¶
# 看启动失败的详细报错
systemctl status bangdream
journalctl -u bangdream -b -n 40
常见根因与命令:
| 现象 | 常见根因 | 命令 |
|---|---|---|
Address already in use |
端口被占用 | ss -tlnp \| grep <port> |
Cannot connect to MySQL |
数据库没起/连不上 | systemctl status mysql |
Module not found |
node 依赖没装/路径不对 | ls /var/www/<app>/node_modules |
| 权限拒绝 | 目录/文件权限不足 | ls -ld /var/www/<app> |
| OOM(Kill) | 内存被吃光 | dmesg -T \| grep -i oom、journalctl \| grep -i oom |
案例 3:数据库连接失败¶
业务起不来、后端报"can't connect to MySQL":
# MySQL 服务与端口
systemctl status mysql
ss -tlnp | grep ':3306'
# 客户端连接测试(需凭据)
mysql -u root -p -e "select 1;"
# 看 MySQL 错误日志
tail -n 50 /var/log/mysql/error.log
# 表满了/连不上也查
mysql -e "show processlist;"
常见根因:MySQL 没 start、账号主机受限(只允许 localhost 但代码用了远程 IP)、密码错、skip-networking、磁盘满导致 MySQL 拒写入。
案例 4:磁盘爆满¶
磁盘满会引发连锁故障(日志写不进去、数据库挂、网站 502)。
df -h # 哪个分区满了
du -sh /var/* | sort -rh | head # 哪拿走了空间;重点看 /var/log、/var/lib
journalctl --disk-usage
# 清理:日志轮转/压缩/截断、删过期备份、清大文件
journalctl --vacuum-time=14d
find /backups -mtime +7 -delete
提示 | 遇到"莫名奇妙全挂了",先看一眼磁盘和内存,往往就是根因。
案例 5:网络时通时断¶
mtr -rwc 20 2.25.183.241 # 看哪一跳丢包
curl -w "code=%{http_code} time=%{time_total}\n" https://learn.bangdream.xyz/
ping -c 100 193.112.201.1 # 长 ping 看丢包率
若只是某个平台访问不了、别的地方正常 → 多为地域/运营商/墙问题;若全丢 → 排查防火墙/安全组/链路。
排查记录表(按需填)¶
| 字段 | 内容 |
|---|---|
| 现象 | 一句话描述 + 错误信息截图/原文 |
| 影响范围 | 哪些入口/用户受影响 |
| 第一步验证 | 用哪条命令得到什么结论 |
| 根因 | 基于哪条证据确认 |
| 修复动作 | 执行了什么 |
| 复验 | 用哪条命令确认已恢复 |
相关命令集合¶
- 服务:
systemctl status <svc>、journalctl -u <svc> -n 50 -p err - 端口:
ss -tlnp - 资源:
df -h、free -h、uptime、top、dmesg -T | grep -i oom - 网络:
dig、nc -zv、curl -v、mtr - 数据库:
mysql -e "show processlist"、SHOW STATUS