线上出问题时,你需要同时看三样东西:日志、数据库、缓存。
传统做法是在三个工具之间反复切换。SDD-Agent 把它们串成一条链路:你给一个 traceId,Agent 自动查日志、查数据库、查 Redis,输出完整的链路分析报告。
一、排查场景
| 场景 | 用户输入 | Agent 动作 |
|---|---|---|
| 接口报错 | "traceId=abc123 帮我看看为什么 500" | 查 SLS 日志 → 定位异常堆栈 → 查 DB 确认数据状态 |
| 接口慢 | "这个接口最近很慢,帮我分析耗时" | 查 SLS 耗时日志 → 拆分 Feign/DB/Redis 耗时占比 |
| 数据异常 | "订单 12345 的状态怎么变成 REOPENED 了" | 查 DB 当前状态 → 查 Redis 缓存 → 查 SLS 操作日志 |
| 缓存不一致 | "用户看到的数据和 DB 不一样" | 查 Redis key 值 → 查 DB 值 → 对比差异 → 定位缓存刷新逻辑 |
二、排查流程
用户提供 traceId / 订单号 / 报错信息
↓
Resource Binding 自动激活(检测到日志/DB/Redis 关键词)
↓
┌──────────────────────────────────────────────┐
│ Step 1:查 SLS 日志 │
│ → 提取异常堆栈、请求参数、响应、耗时 │
│ → 识别涉及的 Feign 调用链路 │
├──────────────────────────────────────────────┤
│ Step 2:查 DB │
│ → 根据日志中的业务 ID 查当前数据状态 │
│ → 对比操作前后的数据变化 │
├──────────────────────────────────────────────┤
│ Step 3:查 Redis │
│ → 查相关缓存 key 的值和 TTL │
│ → 对比缓存值和 DB 值是否一致 │
├──────────────────────────────────────────────┤
│ Step 4:交叉分析 │
│ → 综合日志、DB、Redis 的证据 │
│ → 输出根因分析和修复建议 │
└──────────────────────────────────────────────┘
↓
输出排查报告
三、SLS 日志分析
Agent 调用 SLS MCP 工具,按 traceId 查询日志:
查询条件:
project: my-project
logstore: app-log
query: traceId = "abc123"
from: 2026-10-29 14:00:00
to: 2026-10-29 14:30:00
Agent 提取的关键信息:
├── 异常类型:NullPointerException
├── 异常位置:OrderServiceImpl.java:142
├── 请求参数:{"orderId": "12345", "reason": "商品破损"}
├── Feign 调用链:order-service → inventory-service → merchant-service
├── 耗时分布:
│ ├── Feign 调用:850ms(占 72%)
│ ├── DB 查询:120ms
│ └── Redis 查询:5ms
└── 状态码:500
四、DB 数据验证
Agent 根据日志中的业务 ID 查询数据库,验证数据状态:
-- Agent 自动生成并执行(只允许 SELECT)
SELECT order_id, status, aftersale_status, updated_time
FROM orders
WHERE order_id = '12345';
结果:
┌──────────┬────────┬─────────────────┬─────────────────────┐
│ order_id │ status │ aftersale_status│ updated_time │
├──────────┼────────┼─────────────────┼─────────────────────┤
│ 12345 │ CLOSED │ COMPLETED │ 2026-10-29 14:15:32 │
└──────────┴────────┴─────────────────┴─────────────────────┘
Agent 分析:
订单状态是 CLOSED,售后状态是 COMPLETED,
但日志显示在 COMPLETED 状态下尝试重开 → 触发 NPE
根因:代码中 switch(aftersaleStatus) 对 COMPLETED 没有处理分支,
返回 null 导致后续 .hashCode() 抛出 NPE
五、Redis 缓存验证
Agent 查询 Redis:
Key: order:detail:12345
Type: hash
TTL: 3600s
Value: {
"status": "ACTIVE", ← 缓存中还是 ACTIVE
"aftersaleStatus": "PENDING" ← 缓存中还是 PENDING
}
Agent 分析:
DB 中 status=CLOSED,但缓存中还是 ACTIVE
→ 缓存未及时刷新
→ 根因:状态变更后没有删除/更新缓存 key
→ 建议:状态变更时主动删除缓存,或设置更短 TTL
六、安全约束
⚠️ 排查时的安全边界:
• DB 只允许 SELECT,不允许 UPDATE/DELETE
• Redis 只允许 GET/HGETALL/TTL 等读操作
• 日志查询结果自动脱敏手机号、身份证号
• 生产环境操作需用户显式确认
• 排查结果不写入业务库,只输出分析报告
七、输出报告模板
## 排查报告
traceId: abc123
时间: 2026-10-29 14:15:32
服务: order-service
接口: POST /api/orders/12345/aftersale/reopen
根因:
switch(aftersaleStatus) 对 COMPLETED 状态没有处理分支,
返回 null 后调用 .hashCode() 抛出 NPE。
证据链:
1. SLS 日志显示 NPE at OrderServiceImpl:142
2. DB 确认 aftersale_status = COMPLETED
3. 代码中 switch 只有 PENDING/APPROVED 两个 case
修复建议:
在 switch 中添加 COMPLETED 分支,
或在 default 分支中抛出业务异常而非返回 null。
是否需要我生成修复代码?
八、总结
SDD-Agent 的排查能力来自三个数据源的事实交叉验证:日志告诉你"发生了什么",数据库告诉你"现在是什么状态",缓存告诉你"用户看到的是什么"。三者综合分析,才能定位根因而不是猜。
📌 下一篇预告: 让 Agent 越用越聪明------学习反馈与场景映射
你排查线上问题通常要切几个工具?评论区聊聊。
觉得有用请点赞收藏。