跳到主要内容

故障诊断闭环 — 从发现问题到修复验证,一条链路走通

以前排障 = 查日志 → 猜 → 加日志 → 重跑 → 再猜 → 再加日志……

现在排障 = 看故事 → 点一下 → 到代码 → 修复 → 验证。

传统排障有多痛

场景:线上报错了,用户投诉

没有 dlz-lens 的时候

第 1 步:接到告警 / 用户反馈

第 2 步:查日志系统
→ 搜索 error 关键字
→ 找到异常堆栈
→ 看到 SQL 错误,但不知道是哪个接口触发的
→ 也不知道传入的参数是什么

第 3 步:猜
→ 根据异常里的类名,大概猜到是哪个接口
→ 但这个类可能被好几个地方调用,不确定是哪条路径

第 4 步:加日志
→ 在怀疑的地方加 log.info() 打印参数
→ 加 log.info() 打印 traceId
→ 改代码 → 提交 → 发布到测试环境

第 5 步:重现
→ 测一下,看看能不能重现
→ 不能重现?再猜,再加日志
→ 能重现?看新加的日志输出

第 6 步:定位根因
→ 哦,原来是这个参数传错了
→ 哦,原来是这里 N+1 了
→ 哦,原来是事务里调了 HTTP

第 7 步:修复 → 发布 → 验证

总耗时:30 分钟 ~ 半天,取决于问题好不好猜

核心痛点:信息不全 → 靠猜 → 反复加日志 → 反复重跑。低效、痛苦、依赖经验。

有 dlz-lens 的时候

第 1 步:接到告警 / 用户反馈

第 2 步:打开 dlz-lens → 故事回放
→ 筛选 500 错误的请求
→ 找到出错的那个故事

第 3 步:看故事时间线
→ 一眼看到:第 4 条 SQL 执行失败了
→ 错误信息:Duplicate entry 'xxx' for key 'uk_order_no'
→ 参数是什么、调用者是谁、在不在事务里——清清楚楚

第 4 步:点一下调用者 → 直接跳到代码行
→ IDEA 自动打开,光标定位到出问题的那行
→ 上下文一目了然

第 5 步:修复 → 发布 → 重跑接口 → 看故事验证

总耗时:3 ~ 5 分钟

区别:不是"猜 → 验证 → 再猜",是"看 → 定位 → 修复"。


完整的诊断闭环

dlz-lens 提供的不是一个"看 SQL 的面板",是一条完整的故障诊断链路。

第一步:发现问题

怎么发现?

入口你会看到
实时监控 Tab新出现的红色错误调用、橙色慢调用
故事回放 Tab红色 500 错误的请求、橙色慢请求、紫色 N+1 标签
顶部状态栏错误数突然飙升、慢 SQL 数突然增加

不用盯着控制台等——你可以正常开发、正常测试,有问题的时候过来一看就知道。

第二步:定位根因

从外到内,三层定位:

第一层:哪个请求有问题?

在故事列表里,有问题的请求会用颜色标记出来——红色错误、橙色慢、紫色 N+1。一眼就能挑出来。

第二层:这个请求里哪一步有问题?

点进故事,看时间线。哪步报错了、哪步最慢、哪步看起来不正常——都在时间线上清清楚楚。

第三层:这步是哪行代码触发的?

点一下调用者,直接跳 IDE。到了代码行,上下文就在眼前——为什么会执行到这里、参数怎么传过来的、逻辑是什么——一目了然。

三层定位,层层递进。从"哪个接口有问题"到"哪行代码有问题",不超过 10 秒。

第三步:修复验证

改完代码,重新跑一下接口,再看故事回放:

  • 错误还在吗?→ 验证修复有效性
  • 耗时降下来了吗?→ 验证性能优化效果
  • N+1 消除了吗?→ 验证重构效果
  • 事务范围对了吗?→ 验证事务调整

修复前的故事 vs 修复后的故事,对比一下就知道有没有修好。


常见故障的诊断路径

🔴 场景 1:接口 500 报错

诊断路径:

  1. 故事回放 → 筛选 500 → 找到报错请求
  2. 看时间线 → 找到红色错误的那步调用
  3. 看错误信息 → 知道了是什么异常
  4. 看参数 → 知道了传的是什么值
  5. 点调用者 → 跳代码 → 分析为什么会出错
  6. 修复 → 重跑 → 验证

耗时:3 分钟。


🐢 场景 2:接口很慢

诊断路径:

  1. 故事回放 → 找到慢请求
  2. 看时间线 → 看耗时分布
    • 是某一条 SQL 特别慢?→ 去优化那条 SQL
    • 是 N 条小 SQL 加起来慢?→ 看是不是 N+1
    • 是 Redis 慢?→ 查 Redis
    • 是下游 HTTP 慢?→ 找下游 / 加缓存
  3. 点调用者 → 跳代码 → 看上下文
  4. 优化 → 重跑 → 对比优化前后的故事

耗时:5 分钟。


🔄 场景 3:N+1 问题

怎么发现的:

  • 故事列表里有紫色 N+1 标签
  • 时间线上出现一组长得很像的调用(比如循环查同一个表)
  • 统计里 SQL 数量明显偏多

诊断路径:

  1. 故事回放 → 找到 N+1 标记的请求
  2. 看时间线 → 确认是哪里在循环查
  3. 点调用者 → 跳代码 → 找到循环位置
  4. 改成批量查询 / 预加载
  5. 重跑 → 验证 SQL 数量是不是降下来了

耗时:5 分钟。

以前找 N+1 全靠经验和眼力——看日志里一堆相似的 SQL,猜是哪里循环查的。

现在?dlz-lens 直接帮你标出来,紫色标签明明白白。


⚠️ 场景 4:事务问题

怎么发现的:

  • 故事列表里有黄色"事务风险"标签
  • 时间线上事务竖线特别长(事务过大)
  • 事务里出现了 HTTP / Redis 等不该有的调用

常见事务问题:

问题表现风险等级
事务里调 HTTP事务竖线里有 HTTP 调用🔴 高
事务过大事务里有 10+ 条调用,持续时间长🟠 中
事务里有 N+1事务里循环查数据🟠 中
不必要的事务只读查询也开了事务🟡 低
事务外发 MQMQ 在 COMMIT 之前发🟠 中(可能发了消息但事务回滚)

诊断路径:

  1. 故事回放 → 找到事务风险标记的请求
  2. 看时间线 → 看事务范围里有什么
  3. 点 BEGIN 的调用者 → 跳代码 → 看事务声明在哪
  4. 调整事务范围 / 去掉不必要的事务
  5. 重跑 → 验证事务范围是不是合理了

为什么这是"闭环"

传统排障是开环的——你永远不知道信息够不够,总在猜,总在加日志,反复验证。

dlz-lens 的排障是闭环的:

发现问题 → 定位根因 → 修复代码 → 验证效果
↑ ↓
└────────────────────────────┘
(验证后再发现新问题,继续循环)

每一步都有足够的信息,不需要猜,不需要额外加日志。发现了问题就能定位,定位了就能修复,修复了就能验证。一条链路走通。


真实案例对比

案例:生产环境订单创建偶尔失败

没有 dlz-lens 的排查过程

Day 1: 用户反馈偶尔下单失败

查日志 → 看到 DuplicateKeyException

猜:是不是订单号重复了?

加日志 → 打印订单号生成逻辑

发测试环境 → 没重现出来

Day 2: 继续猜

会不会是并发问题?

加更多日志 → 打印事务状态、打印线程号

压测 → 还是没重现

Day 3: 终于在生产抓到一次

分析日志 → 发现是两个请求生成了同一个订单号

哦,订单号生成器在并发场景下有问题

修复 → 发布

总耗时:3 天

有 dlz-lens 的排查过程

用户反馈偶尔下单失败

打开 dlz-lens → 故事回放 → 筛选 500 错误

找到失败的请求 → 看时间线

第 3 条 INSERT 报错:Duplicate entry 'ORD2026081100123'

点调用者 → 跳到 OrderNoGenerator.java:25

看代码:哦,这个生成器没有考虑并发

修复(加分布式锁 / 用号段模式)

重跑并发测试 → 看故事 → 没有重复了

总耗时:15 分钟

这不是夸张。这是每一个后端开发者都经历过的痛点——信息不够的时候,排障全靠猜,而猜是最浪费时间的。

dlz-lens 给你的,就是足够的信息,让你不用猜。


不只是排障工具

故障诊断闭环是 dlz-lens 最直观的价值,但它的用处不止于此:

场景怎么用节省的时间
开发调试写代码时实时看 IO 调用对不对每次调试省 5-10 分钟
性能优化看故事找瓶颈,不瞎优化每次优化省 30 分钟
Code Review跑一遍接口看故事,找隐藏问题每次 CR 省 15 分钟
新人上手跑核心接口看故事,懂业务流程新人上手时间缩短 50%
技术分享用故事时间线讲解系统架构一听就懂,不用脑补

把这些加起来,一个开发者每周至少能省出 2-3 小时。

而这一切,只需要加一个依赖,加一行配置。