146 lines
13 KiB
Markdown
146 lines
13 KiB
Markdown
# 同步调用依赖与失败传播治理基线
|
||
|
||
## 目的与口径
|
||
|
||
本基线覆盖当前官方 22 个 Maven 模块、15 个可执行服务之间的 OpenFeign、`RestClient`、`WebClient` 与 JDK `HttpClient` 调用。海外安全 Inbox/投影属于 Lastleg 内部子域,不再作为独立服务节点。基线用于识别同步依赖方向、在线请求深度、后台中继、超时、重试、熔断、幂等、错误映射和失败传播,不改变 Finance 或四期业务状态机。
|
||
|
||
“存在双向服务边”不等于“一次在线请求会递归调用”。每条边必须继续区分:
|
||
|
||
- `REQUEST`:用户或设备请求线程内,失败直接影响当前业务结果;
|
||
- `BACKGROUND`:Outbox、Inbox、定时器或导出 Worker 中的同步传输,业务事务已与传输解耦;
|
||
- `INFRASTRUCTURE`:审计、网关会话校验等基础设施调用;
|
||
- `EXTERNAL`:Integration 对第三方供应商的调用。
|
||
|
||
逐客户端可执行清单位于 `scripts/synchronous-dependency-baseline.mjs`,离线合同为 `scripts/synchronous-dependency-contract.test.mjs`。清单逐项冻结 44 个 Feign 与 16 个原始 HTTP 客户端的执行上下文、`READ/WRITE/READ_WRITE`、幂等类型和说明,并从同一事实源输出 REQUEST、BACKGROUND、INFRASTRUCTURE、EXTERNAL 与全图。新增客户端、目标服务、在线边、强连通分量或超时配置时,必须先更新基线并完成调用方与被调用方评审,不能仅修改测试期望以放行。
|
||
|
||
## 当前服务边
|
||
|
||
### OpenFeign
|
||
|
||
| 调用方 | 被调用方 | 客户端数 | 主要上下文 |
|
||
|---|---|---:|---|
|
||
| Auth | IAM | 2 | 登录授权、注册,`REQUEST` |
|
||
| IAM | Auth | 1 | 账号开通/管理,`REQUEST` |
|
||
| IAM | Firstleg | 1 | 客户尺寸默认规则可靠任务投递,`BACKGROUND` |
|
||
| IAM | Warehouse | 1 | 海外仓储费协作,`REQUEST` |
|
||
| IAM | Event Bridge | 1 | 安全事件中继,`BACKGROUND` |
|
||
| Order | Firstleg | 3 | 计价/统一订单查询为 `REQUEST`,入库协作为 Outbox `BACKGROUND` |
|
||
| Order | IAM / File / Warehouse | 各 1 | 资格、图片、仓库守卫,`REQUEST` |
|
||
| Firstleg | Order | 2 | 货物查询与分拆回写,`REQUEST` |
|
||
| Firstleg | IAM / Finance / Integration / Event Bridge / Print | 各 1 | IAM、Integration、Print 为 `REQUEST`;Finance 与 Event Bridge 为 `BACKGROUND` 中继 |
|
||
| Firstleg | File | 7 | 测量、装柜、凭证、报关、拖车等,`REQUEST` |
|
||
| Firstleg | Warehouse | 4 | 主数据、供应商、库位/托盘,`REQUEST` |
|
||
| Finance | Firstleg | 2 | 费用来源/成本快照,事件消费与平台操作混合 |
|
||
| Finance | File / IAM / Warehouse | 各 1 | 凭证、客户、供应商校验,`REQUEST` |
|
||
| File | IAM | 2 | 资质登记为 `REQUEST`;导出 Provider 为 `BACKGROUND` |
|
||
| File | Order / Firstleg / Finance / Warehouse | 各 1 | 导出 Provider,`BACKGROUND` |
|
||
| File | Integration | 1 | OCR 在上传处理请求线程执行,`REQUEST` |
|
||
| Lastleg | Event Bridge | 1 | 跨区事件 Outbox 中继,`BACKGROUND` |
|
||
| Lastleg | 国内 Warehouse | 1 | 合作仓报价快照,`REQUEST` |
|
||
|
||
合计 44 个 Feign 客户端。公共默认连接/读取超时为 3 秒/5 秒;File 的五个导出 Provider 客户端读取超时单独为 15 秒。
|
||
|
||
### 原始 HTTP
|
||
|
||
| 调用方 | 被调用方 | 实现 | 上下文与当前策略 |
|
||
|---|---|---|---|
|
||
| Gateway Overseas | Auth | `HttpPdaSessionValidationClient` | `INFRASTRUCTURE`;总超时 2 秒,异常由网关失败关闭 |
|
||
| Gateway Overseas | Lastleg Security 子域 | `HttpOverseasSecurityValidationClient` | `INFRASTRUCTURE`;Lastleg 内部安全投影实时校验,异常失败关闭,不进入在线业务图 |
|
||
| Lastleg | Warehouse Overseas | 两个 `RestClient` Gateway | `REQUEST`;分别使用 3 秒连接、5 秒读取超时,配置可覆盖,不自动重试 |
|
||
| Lastleg | File | 两个照片 `RestClient` Gateway | `REQUEST`;分别使用 3 秒连接、30 秒读取超时,配置可覆盖;校验响应 code 且失败关闭,不自动重试 |
|
||
| Event Bridge | Firstleg / Lastleg(业务事件与安全投影两个入口) | 三个 JDK `HttpClient` | `BACKGROUND`;连接 3 秒、请求 10 秒,持久化租约和退避由 Event Bridge 专项治理;Lastleg Security 投影不进入在线业务图 |
|
||
| 启用 Common Audit 的服务 | Audit | `HttpAuditSink` | `INFRASTRUCTURE`;当前捕获异常后仅告警,可能让调用方误以为审计已成功,是高优先级失败传播缺口 |
|
||
| Integration | 外部 OCR/船司 | 六个 JDK `HttpClient` | `EXTERNAL`;OCR 默认 10/60 秒,船司默认 10/30 秒,业务重试必须服从供应商和调度契约 |
|
||
|
||
#### Lastleg 四个有界 RestClient
|
||
|
||
四个客户端统一从 `LastlegRestClientFactory` 构建 JDK HTTP 传输,由 `LastlegRestClientProperties` 绑定独立超时。读取超时是单次请求的硬边界;客户端没有 Retry、fallback 或默认成功配置。
|
||
|
||
| 客户端 | 构建与调用路径 | 写操作幂等性 | 默认超时 |
|
||
|---|---|---|---|
|
||
| `HttpUnloadPhotoFileGateway` | `ReceivingContainerController → ReceivingContainerService → UnloadPhotoFileGateway → /internal/file/v1/business-files/**` | `validate` GET 可重复;`upload` 每次写文件和元数据,没有幂等键,禁止自动重试 | 连接 3 秒、读取 30 秒 |
|
||
| `HttpRelabelPhotoFileGateway` | `RelabelPdaController/Service → RelabelPhotoFileGateway → /internal/file/v1/business-files/**` | `validate` GET 可重复;`upload` 没有幂等键,禁止自动重试 | 连接 3 秒、读取 30 秒 |
|
||
| `HttpWarehouseResourceGateway` | `InboundPdaWorkflowService`、PDA 仓内查询/盘点及 Dropship → Warehouse Resource/Pallet 内部接口 | 查询可重复;`reserve` 使用 `reservationKey`,`ensureDropship` 使用业务绑定,release/scrap 由服务端状态收敛;尽管服务端具备业务幂等,客户端仍不自动重试 | 连接 3 秒、读取 5 秒 |
|
||
| `HttpPalletPhysicalGateway` | `PdaPalletOperationService`、`PdaInventoryMoveService` → `/internal/v1/pda-pallet-transitions/**` | 查询可重复;apply/compensate 使用稳定 `operationKey` 与请求哈希,服务端幂等;客户端仍不自动重试 | 连接 3 秒、读取 5 秒 |
|
||
|
||
## 分上下文依赖图
|
||
|
||
### 在线 REQUEST 图
|
||
|
||
在线图只包含用户或设备请求线程中实际执行的服务边。Event Bridge、Outbox、船节点定时任务、导出 Provider 和 Gateway→Lastleg Security 基础设施校验均不计入在线深度。
|
||
|
||
当前在线强连通分量为:
|
||
|
||
`Auth ↔ IAM`;`Firstleg ↔ Order`
|
||
|
||
`IAM → Firstleg` 默认尺寸初始化已退出请求线程,合同现冻结 21 条在线服务边;新增在线边或新增强连通分量直接失败。File 不再属于在线强连通分量;Finance、Lastleg 只指向上述分量或叶子服务,不属于在线环;Gateway Overseas→Lastleg Security 是 `INFRASTRUCTURE`,不是 REQUEST 边。
|
||
|
||
### 后台 BACKGROUND 图
|
||
|
||
后台图包含 Outbox/Inbox、导出 Worker 和定时任务,当前强连通分量为:
|
||
|
||
`Event Bridge ↔ Firstleg ↔ Finance ↔ Lastleg`
|
||
|
||
File 的五个导出 Provider、Order→Firstleg 入库 Outbox、IAM 默认尺寸可靠任务、IAM 安全 Outbox、Firstleg/Lastleg 跨区 Outbox、Firstleg→Finance 费用 Outbox及 Event Bridge 三个消费者均只在后台图中计算。Event Bridge→Lastleg Security 与 Event Bridge→Lastleg 业务事件在服务图上收敛为同一条后台服务边,不形成新的在线业务边或独立安全节点。
|
||
|
||
### 全图
|
||
|
||
全上下文合并后,非平凡强连通分量仍为 8 个服务:
|
||
|
||
`Auth ↔ IAM ↔ Order ↔ Firstleg ↔ Finance ↔ File ↔ Event Bridge ↔ Lastleg`
|
||
|
||
全图只用于部署影响和故障域观察,不能再用于推导在线调用“无限深度”。
|
||
|
||
### 用户入口在线最长简单路径
|
||
|
||
默认在线预算为最多 2 个下游服务跳数。合同对每个已知用户入口枚举全部最长简单路径;下表列出的具体路径均超过预算:
|
||
|
||
| 用户入口 | 最长跳数 | 全部长路径 |
|
||
|---|---:|---|
|
||
| 订单 API | 4 | `Order → Firstleg → File → IAM → Auth`;`Order → Firstleg → File → IAM → Warehouse` |
|
||
| 头程 API/PDA | 4 | `Firstleg → Order → File → IAM → Auth`;`Firstleg → Order → File → IAM → Warehouse` |
|
||
| 财务 API | 5 | `Finance → Firstleg → Order → File → IAM → Auth`;`Finance → Firstleg → Order → File → IAM → Warehouse` |
|
||
| 海外尾程 API/PDA | 3 | `Lastleg → File → IAM → Auth`;`Lastleg → File → IAM → Warehouse` |
|
||
|
||
这些是静态服务边可形成的最长简单路径,不表示每个具体 Controller 都会走完整链;后续入口级调用点治理必须继续以实际 Service 调用证据缩小路径,不能用静态可能性宣称线上已经发生。
|
||
|
||
### 已完成的第一个 REQUEST 边退出
|
||
|
||
`IAM → Firstleg` 的 `CustomerDimensionRuleClient` 默认尺寸初始化已经从 REQUEST WRITE 改为可靠后台编排。IAM 与客户主档同事务持久化稳定 `initializationKey` 的任务,显式维护 `PENDING/READY/FAILED`,由租约调度重试并提供诊断查询和人工重试;审批通过与下单资格在未 READY 时失败关闭。此边现在仅属于 BACKGROUND,在线五服务强连通分量实际拆为 Auth↔IAM 与 Order↔Firstleg 两个子环,未触碰财务、Event Bridge 或四期业务状态机。
|
||
|
||
## 退出顺序
|
||
|
||
1. **冻结与分层。** 先用清单合同阻止未评审新边;为每个客户端补齐 `REQUEST/BACKGROUND/INFRASTRUCTURE/EXTERNAL`、读写语义、幂等键和失败映射。这个阶段不改变业务状态。
|
||
2. **统一失败传播与时间预算。** 为 Feign 和原始 HTTP 明确连接/读取/总超时;默认禁用自动重试,只有具备幂等键且由业务明确拥有退避状态的后台操作可以重试;禁止空数据、默认成功或仅日志告警替代远端失败。
|
||
3. **先退出伪在线环。** File 导出 Provider、Firstleg/Lastleg Event Bridge、Firstleg→Finance 费用投递继续作为后台链路,但必须从在线深度图剥离,并禁止 Worker 消费时无界同步回调。
|
||
4. **退出 `Order ↔ Firstleg` 在线双向命令。** 保留一个方向的权威查询,将反向状态推进改为带版本、幂等和审计的 Outbox/Inbox;不复制 Order 交易状态或 Firstleg 履约状态。
|
||
5. **退出 `Auth ↔ IAM` 在线双向写。** Auth 保持账号与 Token 唯一所有者,IAM 保持客户/RBAC 所有者;注册和账号开通使用可恢复编排,登录授权快照失败关闭,不引入第二套账号事实。
|
||
6. **收敛 `IAM ↔ Firstleg`。** 客户维度规则和客户快照确定单一事实方向;允许短期只读查询,禁止两个服务互相修正对方数据。
|
||
7. **在财务总控确认后退出 `Firstleg ↔ Finance` 回调。** 优先让版本化事件携带 Finance 校验所需的不可变快照或使用单向快照读取,保持 Finance 状态机和 Firstleg 费用事实边界不变。
|
||
8. **收敛 File 相关环。** File 只拥有文件对象与导出任务;业务服务拥有导出数据和业务归属。凭证/照片校验失败关闭,导出 Worker 使用受限批次、超时和显式失败状态。
|
||
|
||
## 错误、重试与熔断基线
|
||
|
||
- 远端 HTTP 非 2xx、响应体 `code != "200"`、空响应和 DTO 不完整是四类不同失败,均不得变成成功或空列表。
|
||
- 在线查询/命令默认不自动重试。若启用重试,必须同时证明方法幂等、请求具有稳定幂等键、最大尝试次数和总时间预算可控。
|
||
- Outbox/Inbox 重试由持久化状态拥有,Feign/JDK 客户端不得再叠加隐式重试造成次数乘法。
|
||
- 熔断打开时返回统一“依赖不可用”错误并保留 request/trace 关联信息,不配置业务成功型 fallback。
|
||
- 404 只有在契约明确“资源不存在”时可映射为领域未找到;连接失败、超时、5xx、空响应必须映射为依赖不可用。
|
||
- Common Audit 当前“只记录告警后返回”列为已知例外,不能据此推广静默降级;其可靠性与业务阻断口径需和审计/总控共同冻结。
|
||
|
||
## 直接受影响验证
|
||
|
||
| 变更范围 | 最低验证 |
|
||
|---|---|
|
||
| 图、客户端或超时配置 | `node --test scripts/synchronous-dependency-contract.test.mjs` |
|
||
| 单个 Feign/HTTP 签名或错误映射 | `mvn -pl <调用方>,<被调用方> -am test-compile`,并运行双方直接相关测试 |
|
||
| Auth/IAM | `mvn -pl auth,iam -am test` |
|
||
| Order/Firstleg | `mvn -pl order,firstleg -am test` |
|
||
| IAM/Firstleg | `mvn -pl iam,firstleg -am test` |
|
||
| Firstleg/Finance | `mvn -pl firstleg,finance -am test`;业务口径先由财务总控确认 |
|
||
| Firstleg/File 或 File/Finance | `mvn -pl firstleg,file,finance -am test`,按实际消费者缩小模块集 |
|
||
| Lastleg 原始 HTTP | `mvn -pl lastleg-service,warehouse-overseas-service,file -am test`;不改变四期状态机 |
|
||
| 全部治理阶段收口 | `mvn -DskipTests validate` 后执行 `mvn test` |
|
||
|
||
以上均为本地离线验证;未经明确授权不启动 Java/Nacos/数据库,不执行 SQL、部署或测试环境 HTTP 验收。
|