说实话,我排障最惨的两次,都不是命令不会,是方向压根就错了。
一次是改了服务器源码之后,页面怎么看都是旧的,我对着IDE助手骂了半天,让他帮我查哪里没改到。折腾了好久,才发现是CDN缓存的问题,服务器上早就改好了,是我自己一直在看旧缓存。
还有一次更想笑——我让助手改的文件,和我盯着看的文件,根本不是同一个。我压力他压力了半天,最后发现是我自己说错了路径。
所以这篇不是来教你背命令的。命令网上一搜一大把。排障真正坑人的地方是顺序错了:上来就改配置、重启服务,把现场信息覆盖掉,之后想复盘都没得查。
(当然,如果你跟我一样,有时候最后还是靠 reboot 解决问题的——那也很正常,但至少先把日志保存一份。)
下面是一套可以直接抄的流程:先保留现场,再缩小范围,最后验证根因。
一、先定边界:到底坏到什么程度
先回答三个问题:
- 影响范围:全量用户,还是部分请求?
- 起始时间:从什么时候开始异常?
- 变化事件:故障前有没有发布、配置变更、机器重启?
这一步不是“找答案”,是避免盲查。
二、先看现象,再看原因
建议固定这个顺序:
- 服务状态:进程是否存活,是否在频繁重启
- 错误日志:先抓最近 100~300 行错误
- 上游依赖:数据库、缓存、外部 API 是否超时
- 资源瓶颈:CPU、内存、磁盘、句柄是否打满
三、常用命令(可直接复制)
systemd 服务
systemctl status your-service --no-pager
journalctl -u your-service -n 200 --no-pager
journalctl -u your-service --since "30 min ago" --no-pager
Nginx / Web 服务
tail -n 200 /var/log/nginx/error.log
tail -n 200 /var/log/nginx/access.log
grep -E " 5[0-9]{2} " /var/log/nginx/access.log | tail -n 50
Docker 容器
docker ps --format "table {{.Names}} {{.Status}}"
docker logs --tail 200 your-container
docker inspect your-container --format '{{.State.RestartCount}}'
四、把“报错”翻译成“可验证假设”
比如日志里出现 connection timeout,不要直接下结论“网络有问题”,先拆:
- 假设 A:下游服务不可达
- 假设 B:DNS 解析异常
- 假设 C:连接池耗尽
然后逐条验证:
# 连通性
nc -zv downstream-host 5432
# DNS
getent hosts downstream-host
# 本机连接数
ss -s
每次只验证一个假设。 一次改三四处,就算恢复了也不知道是哪条生效的。
五、两个最容易犯的错
一上来就重启——重启可能暂时恢复,但现场没了,后续很难复盘。先抓日志和状态,再决定要不要重启。
一次改好几处配置——单点变更,记录变更前后的结果,才知道到底是哪里修好的。
六、10分钟排障模板
- 记录故障开始时间与影响范围
- 保存当前状态(status / log / top)
- 抓最近错误日志,标注首个异常时间
- 列 2~3 个假设,按成本从低到高验证
- 只做一处最小变更并观察
- 记录结论:根因、处理动作、怎么预防下次
排障能力的核心不是背命令,是用可复现的方法缩小不确定性。当然,reboot 永远是最后的退路——但能不用就不用,至少先把日志留下来。