线上故障应先通过监控告警和日志定位问题入口,再分网络、进程、资源层深入分析根因,最后用精简复盘报告推动可执行改进落地。

快速锁定问题发生位置
线上出问题,第一反应不是重启,而是确认影响范围和故障入口。先看监控告警(如 Prometheus + Grafana),重点关注 CPU、内存、磁盘 I/O、网络连接数、HTTP 5xx 错误率、服务响应延迟突增等指标。同时查 服务日志,用 journalctl -u service-name -n 200 --since "2024-04-05 14:00" 快速拉取指定时间窗口的日志;如果是容器环境,用 kubectl logs -n ns pod-name --since=10m 定位异常输出。
常见线索包括:
- 日志中反复出现
Connection refused或timeout—— 往往指向下游依赖不可用或超时配置过短 - 大量
OOMKilled事件 —— 内存泄漏或资源限制设置不合理 -
dmesg输出包含Out of memory: Kill process—— 系统级内存耗尽,需结合top -o %MEM查高内存进程 -
ss -tulnp | grep :端口显示端口未监听 —— 服务根本没起来,或启动失败静默退出
深入分析根因的常用命令组合
不能只看表面现象。比如服务“假死”,可能进程还在但不响应请求。这时要分层验证:
- 网络层:用
curl -v http://localhost:8080/health或telnet localhost 8080测试本地连通性;再用tcpdump -i lo port 8080 -w debug.pcap抓包确认是否有请求进来、是否有响应发出 - 进程层:用
strace -p PID -e trace=network,io,process观察进程系统调用卡在哪儿(如阻塞在read()或connect()) - 资源层:用
lsof -p PID查打开文件数是否打满;cat /proc/PID/status | grep -E "VmRSS|Threads"看实际内存占用与线程数是否异常飙升 - JVM 应用额外加:
jstack PID > jstack.out查线程阻塞/死锁;jstat -gc PID看 GC 是否频繁
写一份有行动价值的复盘报告
复盘不是写检讨,是为下次少踩坑。报告结构建议精简务实:
- 时间线:精确到分钟,标注关键操作(如“14:22 发布 v2.3.1”、“14:27 监控告警触发”、“14:35 执行回滚”)
- 根因结论:一句话说清,避免模糊表述。例如:“因新版本引入的 Redis 连接池未设置最大空闲数,导致连接持续增长并耗尽系统文件描述符”
- 验证方式:说明这个结论如何被证实(如“复现步骤 + strace 日志 + lsof 统计对比”)
-
改进项清单:每条必须可执行、可验收。例如:
✓ 增加连接池 maxIdle 配置,默认值改为 32
✓ 上线前增加 fd 数压测检查项(ulimit -n≥ 65536)
✓ 在 CI 中加入健康检查探针自动校验(curl -f http://localhost:8080/readyz)
把改进真正落地,而不是放进待办列表
很多复盘止步于“已记录”,结果同类问题三个月后重演。推动落地的关键动作:
- 明确每项改进的 负责人 + 截止时间,并在团队周会同步进展
- 涉及配置变更的,必须走配置中心或 GitOps 流水线,禁止手工改生产服务器
- 新增的监控指标、告警规则、健康检查路径,上线后 48 小时内由值班同学确认是否生效
- 对高频问题(如 OOM、DNS 解析失败),沉淀成 自动化巡检脚本,每天凌晨跑一次,结果推送到运维群
事故的价值不在发生,而在被读懂。每一次复盘,都是把混沌经验转成确定性防御能力的过程。不复杂但容易忽略。










