From 61d6c3779bd6da5e70359f7d5c8336185e6c1dba Mon Sep 17 00:00:00 2001 From: windyboy Date: Wed, 16 Sep 2026 11:08:13 +0800 Subject: [PATCH] =?UTF-8?q?docs(acm2-75):=20=E6=B6=88=E9=99=A4=E8=A7=84?= =?UTF-8?q?=E8=8C=83=E5=86=85=E9=87=8D=E5=A4=8D=E5=AE=9A=E4=B9=89=E5=B9=B6?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E6=98=A0=E5=B0=84=E4=B8=8E=E6=8C=87=E9=92=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/contracts/interface-contract.md | 2 +- docs/implementation.md | 2 +- docs/specification.md | 34 +++++++++++----------------- 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/docs/contracts/interface-contract.md b/docs/contracts/interface-contract.md index b00953e..e81c616 100644 --- a/docs/contracts/interface-contract.md +++ b/docs/contracts/interface-contract.md @@ -54,7 +54,7 @@ AODB 经 CIIMS adapter 把 XML 报文写入 `CMINMSGS`,格式以架构指定 跨航班顺序不构成契约。 -测试环境须使用独立的数据库、Redis 与 Kafka 主题,且不连接生产信箱(`OPS-3`)。 +测试环境与生产隔离的前提见 [specification.md](../specification.md) 的 `PRE-9`(`OPS-3`)。 ## 存储读写边界 diff --git a/docs/implementation.md b/docs/implementation.md index 88c9b1f..7d09e53 100644 --- a/docs/implementation.md +++ b/docs/implementation.md @@ -327,7 +327,7 @@ PENDING → SENT → DONE 清理范围只含「终态且已回填」;保留期内同身份去重成立(`INV-9`)。 -**时间常数排序**:`R ≤ R_keep` 的定义与理由见 [specification.md](specification.md)「契约数值」,本文件不复述。只补一条实现口径:保留期计的是**终局之后**的时间,不是入队之后——终态行未了结回填时不进入候选。 +**时间常数排序**:`R` 的取值与依据见 [reference.md](reference.md) 的 `PARAM:msgx.pipeline.overdue-backfill`,`R_keep` 的下界见 [specification.md](specification.md) 的 `C-7`,本文件不复述。只补一条实现口径:保留期计的是**终局之后**的时间,不是入队之后——终态行未了结回填时不进入候选。 **其余清理** diff --git a/docs/specification.md b/docs/specification.md index a05564c..b974dbc 100644 --- a/docs/specification.md +++ b/docs/specification.md @@ -1,8 +1,8 @@ # 规范:术语、契约、前提、不变量与声明边界 -本文定义 msgexchange-v2 的术语、外部契约、前提、不变量与声明边界。 +本文定义 msgexchange-v2 的术语、外部契约 `C-x`、前提 `PRE-x`、不变量 `INV-x`、声明边界 `CLM-x`、待确认 `Qn`、当前已知偏差 `G-NAME` 与验证映射。 -内容取自 [requirements.md](requirements.md)、[architecture.md](architecture.md) 与 [contracts/interface-contract.md](contracts/interface-contract.md);机制与数据模型见 [implementation.md](implementation.md),参数与指标见 [reference.md](reference.md)。 +内容取自 [requirements.md](requirements.md)、[architecture.md](architecture.md) 与 [contracts/interface-contract.md](contracts/interface-contract.md)。机制与数据模型见 [implementation.md](implementation.md),参数与指标见 [reference.md](reference.md)。 `C-x`、`PRE-x`、`INV-x`、`CLM-x`、`Qn`、`G-NAME` 只在本文件定义;ID 语法见 [README.md](README.md)。 @@ -47,7 +47,7 @@ - **C-14** 本系统不建表、不改表结构、不迁移 schema、不清数据,也不写共享历史表。 - **C-15** 处理标记只在空值上写入处理完成时刻,写完不回撤、不覆盖已有值。`(本系统单方承诺)` - **C-16** 回填失败的行保留记录并告警,记录在对应信箱行被清除前保持可查。`(本系统单方承诺)` -- **C-30** 信箱读取口径:按配置周期读取「处理时间为空」的行,按编号升序、每批有上限;单活动实例运行,不引入并行消费者。 +- **C-30** 本系统读取信箱不加锁、不阻塞写入方,读取谓词、顺序与批量以 `INV-2b` 为准;除回填处理标记(`C-15`)外不写信箱。 - **C-34** 切换与回退以信箱处理标记交接(`OPS-4`、`PRE-1`):切回旧系统前,「已终态但未回填」的行必须清零——每条终态行的处理标记都已写上才算交接完成。放弃自动重试的行标记仍为空(放弃不等于标记已确认),本系统没有任何能阻止旧系统消费它的可观察状态(`C-15` 只填空值、不覆盖):必须先人工恢复重试至打标,或与库方另行定处置(`Q9`);否则这些行切回后会被旧系统再处理。已登记、未到处理完成的消息同样没有交接状态。 待确认:在途消息的回退处置(`Q21`)。 @@ -75,9 +75,8 @@ - **C-29** 对外投递按至少一次设计,不承诺端到端恰好一次:应用重启与待发事件重发都可能让同一条消息多发一次。主题 `msg` 上同一 `FLID` 的变更保序,跨 `FLID` 不承诺顺序;`schd` 不在本条保序范围内。 待确认:Kafka key 与分区规则(`Q4`)。 - **C-31** admin-api 直接读取本系统写入的静态参考数据表;本系统不调用 admin-api,也不从它拉取、补全或合并数据。 -- **C-32** Redis 航班投影的读取口径:网页客户端与 `GET /all/flights` 读同一份投影,返回当前全部动态航班(不含共享航班)、不分页;投影只由本系统写入和移除,不是权威、也不存处理状态;Redis 异常时报错,不返回空列表(`INV-24`)。 +- **C-32** Redis 航班投影对消费方的读取口径以 `INV-24` 为准。 待确认:投影 key/value 结构与网页客户端读取约定(`Q20`)。 -- **C-35** 测试环境的实例使用独立的数据库、Redis 与 Kafka 主题,不连接生产信箱(`OPS-3`)。`(本系统单方承诺)` ### 2.5 已作废条款 @@ -101,8 +100,7 @@ | PRE-6 | 信箱与自有 PG 之间没有跨库事务 | 回填与清除都不能声称原子 | 架构事实 | | PRE-7 | 报文不可变:同一业务身份的重发是同一内容 | 上游改发正文会被判为重复并静默跳过 | 待确认 `Q15` | | PRE-8 | `FLID` 在保留期内不复用(见 `C-21`) | 「只进不退」的合并可能压掉新航班事件,旧的删除标记可能删掉在用航班 | 待确认 `Q16` | - -运行约束:测试环境的实例使用独立的数据库、Redis 与 Kafka 主题,不连接生产信箱(`OPS-3`)。 +| PRE-9 | 测试环境与生产隔离:测试实例使用独立的数据库、Redis 与 Kafka 主题,不连接生产信箱 | 测试结论与隔离验收(`OPS-3`)失效 | 部署与配置约束 | ## 4. 不变量 @@ -137,7 +135,7 @@ ### 4.3 投影、投递、历史与参考数据 -- **INV-23** Redis 投影写成功才算处理完成。失败分两类:PG 事务提交前失败,事务整体回滚、消息保持未完成(`US-03` AC3);投影写失败发生在事务提交后,不回滚已提交的业务结果,保持未完成、下轮重做投影与后续步骤(`US-05` AC4)。两类都不置终态、不回填、不投递。 +- **INV-23** 航班类消息(增量、删除、日计划)的 Redis 投影写成功才算处理完成。失败分两类:PG 事务提交前失败,事务整体回滚、消息保持未完成(`US-03` AC3);投影写失败发生在事务提交后,不回滚已提交的业务结果,保持未完成、下轮重做投影与后续步骤(`US-05` AC4)。两类都不置终态、不回填、不投递。 - **INV-24** Redis 航班投影只由本系统写入和移除;`GET /all/flights` 与网页客户端读同一份,返回当前全部动态航班(不含共享航班),不分页;Redis 异常时报错,不返回空列表伪装成功。 - **INV-25** 处理记录清理:只删「已有终态且已回填」并超过保留期的记录,未完成的不删,保留期可配置;未映射字段的记录不随处理记录到期清理(`US-05` AC3)。 - **INV-26** 静态参考数据按类别与编号保存,新消息覆盖旧记录;全量消息整体替换,增删改消息逐条处理;字段为空表示「当前没有值」,不是删除。 @@ -164,7 +162,7 @@ | CLM-6 | 单实例内按信箱编号升序的 FIFO 调度 | `PRE-5`、`INV-3` | 能 | 只声明按编号排序;「编号即到达顺序」依赖 `PRE-2`(`Q2`),未定案前不声明真实到达顺序 | | CLM-7 | 主题 `msg` 上同一 `FLID` 内保序 | `INV-10`、`C-29`、`D2` | 不能 | `D2` 只保证单分区内生产顺序;同一 `FLID` 落同一分区依赖按 `FLID` 作 key 的分区规则(`Q4`)。跨 `FLID` 不承诺;不覆盖 `schd` | | CLM-8 | 出站交付承诺只到落信 | `C-24` | 能 | 只覆盖落信;ACK 与错误列语义未确认(`Q10`) | -| CLM-9 | 处理标记的写入时刻不等于处理完成的时限 | — | 不能 | 扫描周期不构成完成时限;批次积压与单行重试都会延长实际延迟 | +| CLM-9 | 消息将在某个时限内完成处理 | — | 不能 | 处理标记的写入时刻不是完成时限:扫描周期、批次积压与单行重试都会延长实际延迟 | | CLM-10 | 容量与吞吐量级 | — | 不能 | 无实测数据,取得信箱日量、峰值与单报文上限后重估 | | CLM-11 | 配置不完整时拒绝启动;「双实例同时启动只允许一个处理」无系统侧机制承载 | `OPS-1`、`PRE-5` | 启动拒绝能;双实例验收不能 | 运行时跨实例互斥不在此版设计内——不引入并行主泵或分布式锁是非目标(requirements「范围与非目标」),单实例靠部署保证(`PRE-5`);达成方式待 `Q29` | @@ -243,8 +241,9 @@ | 不变量 | 需求验收 | 要观察的结果 | |---|---|---| | INV-2b | `US-01` AC1/AC2/AC4 | 扫描重来与重启后登记数不变,行不丢 | -| INV-2b、C-28 | `US-02` AC1~AC5 | 兼容入口写入的行与上游投递同路径被发现、登记;非法报文不落信、失败不返回编号 | -| INV-3 | `US-03` AC1 | 队头未完成时,后面的消息不被处理 | +| INV-2b、C-28 | `US-02` AC1~AC5 | 兼容入口接受三种媒体类型、默认 UTF-8;空报文、超上限、非法 XML 不落信并返回错误,解析禁用外部实体与外部资源;成功返回编号且只表示落信;内网来源由网络层配置核对;写入的行与上游投递同路径被发现、登记 | +| INV-3 | `US-01` AC3、`US-03` AC1 | 队头未完成时,后面的消息不被处理;处理顺序为编号升序 | +| CLM-6、PRE-2 | `US-01` AC3 | 「编号即到达顺序」的到达顺序声称待 `PRE-2`(`Q2`)定案,当前只声明按编号排序(`CLM-6`) | | INV-30 | `US-03` AC2/AC5 | 死信与跳过留档且无业务副作用;错误在对应处理记录上可查 | | INV-6、INV-16 | `US-03` AC3 | 失败回滚后消息仍在未完成;已提交结果不被副作用回滚 | | INV-7、INV-8 | `US-10` AC1/AC2 | 标记只写一次;重启后继续,写不上的有记录与告警 | @@ -264,19 +263,12 @@ | INV-23 | `US-05` AC4、`US-06` AC1 | 投影写失败的消息下轮仍被处理 | | INV-24 | `US-12` AC1/AC2 | 返回全部非共享航班,且与 Redis 一致;Redis 故障时返回错误 | | INV-25 | `US-11` AC1/AC2 | 未完成的记录不被删除 | -| INV-26、INV-27 | `US-13` AC1~AC5 | 失败类别的已有记录不变;参考数据落独立数据表供 admin-api 只读(`C-31`) | +| INV-26、INV-27 | `US-13` AC1~AC5 | 全量消息整体替换、增删改消息逐条生效;字段空值保存为「当前没有值」而非删除;失败类别的已有记录不变;参考数据落独立数据表供 admin-api 只读(`C-31`) | | INV-28 | `US-14` AC1~AC4 | 按判史条件与定时选出候选;历史写入失败的航班仍在实时数据中,单个失败不影响其他 | | CLM-4(留案告警) | `US-10` AC2 | 一直写不上的行有记录与告警 | | CLM-8(止于落信) | `US-09` AC1~AC3 | 请求落信即交付、写入结果不明不重发;在途唯一、超时与 `EROR` 定位告警待 `G-REQ-TRACK`、`G-REQ-OPEN-UNIQUE` 闭合后验证,匹配依据见 `Q5` | | CLM-9(不承诺完成时限) | `OPS-2` | 积压、处理失败、投递失败、回填失败各有指标与告警(架构「总体架构」) | -| CLM-10(容量假设) | `OPS-2` | 上线前用现场量级重估 | +| CLM-10(容量假设) | 无对应运行验收 | 上线前用现场量级重估,取值见 [reference.md](reference.md)「参数注册表」 | | C-34 | `OPS-4` | 回退演练:回填了结后切回,旧系统不重处理已产生业务效果的消息;在途窗口处置见 `Q21` | | CLM-11(单实例防线) | `OPS-1` | 配置错误启动失败测试可验收;「双实例同时启动只允许一个处理」未闭环——系统无运行时互斥,达成方式待 `Q29` | -| C-35(测试隔离承诺) | `OPS-3` | 测试环境配置核对:独立数据库、Redis 与 Kafka 主题,不连接生产信箱 | - -## 9. 契约数值 - -| 量 | 定义处 | -|---|---| -| 原文保留期下界 | `C-7` | -| 处理记录保留期 | `INV-25` | +| PRE-9(测试隔离) | `OPS-3` | 测试环境配置核对:独立的数据库、Redis 与 Kafka 主题,不连接生产信箱 |