1. 这张地图解决什么问题
前 48 篇文章已经解释业务边界、接口、状态、表、MQ、异常和回归。本篇增加“按一笔真实请求还原现场”的横向视角:
- 同一业务可能从 PC、App、Inner、OpenAPI、MQ、回调或定时任务进入,实际走哪条链。
- 每段代码当前能用什么日志、业务键和请求 ID 证明已经执行。
- 每一步读取什么事实、写入什么表、字段从什么值变成什么值。
- 数据库事务到哪里结束,哪些 MQ、Provider、缓存、文件和报表动作发生在事务外。
- 链路断裂时,怎样判断是请求未进入、业务回滚、异步未发、下游失败还是回调未落账。
这不是第二份业务说明。业务规则仍回到 01-48 对应专题;本篇负责统一追踪语言、覆盖索引和跨模块证据闭环。
2. 统一五段链路
flowchart LR
A["请求入口"] --> B["Controller/Consumer"]
B --> C["Service/Factory/Provider"]
C --> D["Model、业务表、缓存"]
D --> E["MQ、外部系统、报表"]
E --> F["回调、补偿、最终查询"]
| 链路段 | 必查内容 | 常用关联键 | 当前主要证据 |
|---|---|---|---|
| 请求入口 | URL/交易码/任务方法、请求体、登录上下文、网关 | path、transCode、tradeCode、requestId | Nginx/网关、Controller 方法、OpenAPI Mongo 日志 |
| 同步业务 | 参数校验、权限、状态前置、事务、行锁 | sid、业务单号、主键、来源单号 | CI/Monolog/业务日志、异常响应、数据库事务结果 |
| 数据事实 | 主表、明细、库存、金额、状态、软删 | billNo、srcOrderNo、orderId、skuId | MySQL 业务表、Redis、Mongo、ES |
| 异步副作用 | destination、routing key、Provider 请求、文件任务 | msgId、业务单号、request_id | MQ 生产/消费日志、Provider 日志、下游请求日志 |
| 终态恢复 | 回调、重试、补偿、报表同步、人工核对 | 外部单号、OA号、支付单号、运单号 | Notify/Task 日志、回调表、业务终态、报表延迟 |
3. 业务键优先级
排查时不要只靠时间范围。优先从最稳定的业务键向两侧扩展:
| 优先级 | 键 | 典型用途 | 组合要求 |
|---|---|---|---|
| P0 | sid + billNo | 采购、销售、出库、退货、调拨 | 分表查询必须带 sid |
| P0 | sid + srcOrderNo/srcOrderId/srcOrderType | E站、秒杀、渠道、预订单转内部单 | 防止跨服务站或跨来源误关联 |
| P0 | payOrderNo/oa_number/taskNo/msgId | 支付、OA、GPDA、MQ | 同时关联本地业务单号 |
| P1 | orderId + detailId/skuId/invId | 主明细、库存、部分关闭 | 数量核对必须落到明细 |
| P1 | requestId/request_id | OpenAPI、Provider、微服务 | 只能覆盖实际透传该字段的链路 |
| P2 | 用户、路径、绝对时间 | 没有业务单号的失败请求 | 必须带时区、服务和窄时间窗 |
4. 日志证据的真实边界
flowchart TD
A["获得业务键和绝对时间"] --> B["查入口访问日志"]
B --> C{"请求进入 DGJ 吗"}
C -->|"否"| D["查网关、路由、鉴权和客户端"]
C -->|"是"| E["查 Controller/Service 或异常响应"]
E --> F{"本地事务提交吗"}
F -->|"否"| G["按错误和回滚前置定位"]
F -->|"是"| H["查主表、明细和状态"]
H --> I{"存在异步或外部调用吗"}
I -->|"是"| J["查 MQ/Provider/下游/回调"]
I -->|"否"| K["核对最终查询和页面口径"]
J --> K
- 本地:从
application/logs/、容器挂载日志、类名和方法名开始。 - 预发:按 DGJ 节点、接口路径、业务单号和下游 Provider 请求日志查询。
- 生产:Kibana 使用绝对时间、时区、服务、路径、业务键和错误摘要;默认只读。
- 没有显式日志的代码段,以“入口响应 + 事务后数据 + 下一段日志”构造夹逼证据,并把缺失日志记为可观测性缺口。
- 文档只保存查询方法和脱敏关键字,不保存 Token、Cookie、真实手机号、客户数据或完整原始日志。
5. 逐步数据变化记法
| 写法 | 含义 | 示例 |
|---|---|---|
无 -> 新记录 | INSERT | 提交订单新增主单和明细 |
A -> B | 状态替换 | billStatus: 待支付 -> 待出库 |
+qty/-qty | 原子增减或算术更新 | locked_qty + order_qty |
旧快照 -> 新快照 | 编辑时重建事实 | 采购编辑先冲销旧库存影响再写新值 |
未设置 -> 外部单号 | 回调补充 | OA、支付、运单号回写 |
0 -> 1 软删 | 逻辑删除 | 历史记录仍保留,不等于物理删除 |
每次记录都要补充单位、分片、事务和回查键。金额不能只写“增加”,要写元/分;库存不能只写“扣减”,要写 sid + invId/skuId + 仓库 + 货位 维度。
6. 01-48 追踪层覆盖索引
| 批次 | 文章 | 主要追踪对象 | 当前状态 |
|---|---|---|---|
| T1 | 01-08 | 五类入口、商品库存、采购、销售、秒杀、移动商城、渠道、财务/MQ/OA | 已完成 |
| T2 | 10-18 | 表/状态/API/MQ 字典和采购、销售、库存、秒杀、支付排查 | 已完成 |
| T3 | 19-25 | 权限、Excel、搜索缓存、报表、外部系统、本地日志、公共文件 | 已完成 |
| T4 | 26-32 | PDA、调拨、对账、售后、税票、金融、授信资金池 | 已完成 |
| T5 | 33-40 | 知识库、轮胎、账号、总分店、客户营销、配送、机器人、数据修复 | 已完成 |
| T6 | 41-48 | 报价、电池、首配、大客户、成本、地址、消息、OpenAPI | 已完成 |
2026-07-22 文章级审计为47/47,只表示每篇文章具备总追踪表。用户要求的最终粒度是文章内部每个子模块各自闭环,当前已拆分 416 个子模块,进度与明细见各业务子模块独立链路覆盖矩阵。在416/416前,不将本表状态解释为最终完成。
第 09 篇是规划,不作为请求链路对象。每篇完成后必须在原文增加“请求-日志-数据变更追踪卡”,本索引再改为已完成。
7. 一次排查应留下的证据包
现象与期望
绝对时间与时区
环境、调用方、入口路径/交易码
sid + 主业务单号 + 来源单号
脱敏请求字段和响应业务码
Controller/Consumer 与 Service 方法
入口日志、Provider/MQ 日志、下游日志关键字
事务后主表/明细/库存/金额/状态只读查询
字段旧值 -> 新值或未变化
失败层、重试/补偿边界
最终验证和仍待环境确认项
8. 禁止形成的错误结论
- 只有 HTTP 200 就认为业务成功。
- 只有主表状态正确就认为明细、库存、金额和下游都正确。
- 只在 DGJ 日志里搜不到就认为请求没发生。
- 把代码中的建议日志当成生产已经存在的日志。
- 用一个
requestId推断所有跨系统都透传同一个 Trace ID。 - 不带
sid直接查分表或跨站点业务单号。 - 用报表结果代替业务库终态,忽略 ETL 延迟。
- 直接改表制造“正确结果”,却没有恢复消息、缓存、索引和下游事实。
9. 代码与项目证据入口
| 证据 | 路径 |
|---|---|
| 项目代码地图 | doc/ai/project/code-map.md |
| 项目数据地图 | doc/ai/project/data-map.md |
| 项目日志地图 | doc/ai/project/log-map.md |
| 入口控制器 | application/controllers/ |
| 新旧 Service | application/Services/、application/service/ |
| Model 和分表 | application/models/、application/config/tables.php |
| Provider | application/Providers/ |
| MQ/回调/任务 | application/controllers/tasks/、application/Services/Mq/MqSer.php |
| 状态和类型 | application/KzData/Enums/ |
10. 验收结论
追踪层的完成标准不是“又增加了一张大图”,而是任意拿一个脱敏业务单号,阅读者能按本文和对应模块文章回答:请求从哪里进、走了哪条分支、每段有什么日志证据、每一步哪些表字段发生变化、事务和异步边界在哪里、最终怎样只读验证。