diff --git a/docs/specification.md b/docs/specification.md index d5cbc2a..6198545 100644 --- a/docs/specification.md +++ b/docs/specification.md @@ -24,7 +24,7 @@ | 落信 | 报文写入信箱成为一行;入站由 CIIMS adapter 或兼容入口写入,出站由本系统写入 `COUTMSGS`;入站报文写进信箱后可能尚未登记。 | | 登记 | 本系统在自有 PG 为这条报文建立处理记录,排队等待处理。 | | 处理完成 | 这条消息的结果已经确定——业务改动生效,或明确跳过、进入死信;之后才回填信箱标记、发 Kafka。 | -| 回填 | 把处理标记写回信箱行。 | +| 回填 | 处理完成后,把完成时刻写回信箱行的处理时间字段,告知上游该消息已处理。 | | 投递 | 读待发事件,发往 Kafka。 | | Redis 投影 | 供网页客户端(`GET /all/flights`)查询的航班投影,内容来自自有 PG 当前态;读写边界见 `INV-24`。 | | 自有 PG | 本系统唯一的业务数据库;航班当前态、管道记录与静态参考数据都在这里。 | @@ -40,33 +40,37 @@ - **C-3** 信箱编号不复位、不复用、不回退,含表轮换、备份恢复与自增归零。不丢消息依赖这条(`PRE-2`、`PRE-3`)。`(待确认 Q2)` - **C-4** 报文行不可变:同一业务身份(`SNDR`、`TYPE`、`STYP`、`SEQN`)的重发是同一内容。`(待确认 Q15)` -- **C-5** 处理标记即处理时间列:本系统只写完成时刻、只填空值(`C-15`),不在该列引入状态码等其它语义;死信、跳过与回填失败的原因记在自有 PG。 +- **C-5** 处理标记即处理时间列:不在该列引入状态码等其它语义,死信、跳过与回填失败的原因记在自有 PG;写规则见 `C-15`。 待确认:处理时间列的列名、类型与可空性(`Q7`)。 - **C-6** 原文的保留期与清除时机由库方定;本系统不承诺清除时间,只要求不早于 `C-7` 的下界。`(待确认 Q7、Q9)` -- **C-7** 保留期下界分两层:回填重试期间信箱行必须仍在、标记列仍为空——`US-10` AC2 的重试需要的是可更新的行,不是原文;处理未完成的消息原文必须仍在——下轮重处理(`US-03` AC3)以原文为依据。`(待确认 Q7、Q9)` -- **C-8** 清除由库方执行;本系统不执行 DDL、不清数据、不写共享历史表(`C-14`)。清除是否需要标记以外的证据,另行确认。`(待确认 Q9)` +- **C-7** 保留期下界分两层:回填重试期间,信箱行必须仍在、标记列仍为空(`US-10` AC2 的重试需要可更新的行);处理未完成的消息,原文必须仍在(`US-03` AC3 的重处理以原文为依据)。`(待确认 Q7、Q9)` +- **C-8** 清除由库方执行;本系统不执行 DDL、不清数据、不写共享历史表(`C-14`)。 + 待确认:清除是否还需要处理标记以外的证据(`Q9`)。 - **C-9** 清除的方案与 DDL 授权由库方定,本系统不参与选型。`(待确认 Q9)` - **C-10** 信箱时间列由写入方写入,其时钟基准须可解释(`PRE-4`)。 待确认:时区与允许偏斜(`Q7`)。 -- **C-12** 原文被提前清除时,本系统不补造原文,也不把这类消息当成功。已登记的消息无法解码,也不能按 `US-03` AC2 判为非法——原文不可得不等于报文非法;未定前按处理失败保持未完成并告警(`US-03` AC3),队头因此阻塞是显式接受的代价,处置口径待 `Q22` 定案。信箱行在登记前整行消失时,扫描谓词对该行不可见,本系统无法发现其存在;防线只剩 `C-7` 的保留期下界由库方遵守(`Q9`)。`(本系统单方承诺)` +- **C-12** 已登记的消息原文被提前清除时,本系统不补造原文,也不把这类消息当成功:原文不可得不等于报文非法,不能按 `US-03` AC2 处置;未定前按处理失败保持未完成并告警(`US-03` AC3),该消息占住处理顺序。 + 信箱行在登记前整行消失的,扫描谓词对其不可见,本系统无法发现;防线只剩 `C-7` 的保留期下界由库方遵守(`Q9`)。`(本系统单方承诺)` + 待确认:原文不可得消息的处置口径(`Q22`)。 - **C-14** 本系统不建表、不改表结构、不迁移 schema、不清数据,也不写共享历史表。 - **C-15** 处理标记只在空值上写入处理完成时刻,写完不回撤、不覆盖已有值。`(本系统单方承诺)` -- **C-16** 回填失败的行保留记录并告警,记录在对应信箱行被清除前保持可查。`(本系统单方承诺)` +- **C-16** 回填失败时在自有 PG 保留记录并告警;该记录在对应信箱行清除前保持可查。`(本系统单方承诺)` - **C-30** 本系统读取入站信箱 `CMINMSGS` 不加锁、不阻塞写入方,读取谓词、顺序与批量以 `INV-2b` 为准;除回填处理标记(`C-15`)与兼容入口落信(`C-28`)外不写 `CMINMSGS`。`COUTMSGS` 的写入见 `C-24`。 -- **C-34** 切换与回退以信箱处理标记交接(`OPS-4`、`PRE-1`):切回旧系统前,「已终态但未回填」的行必须清零——每条终态行的处理标记都已写上才算交接完成。放弃自动重试的行标记仍为空(放弃不等于标记已确认),本系统没有任何能阻止旧系统消费它的可观察状态(`C-15` 只填空值、不覆盖):必须先人工恢复重试至打标,或与库方另行定处置(`Q9`);否则这些行切回后会被旧系统再处理。已登记、未到处理完成的消息同样没有交接状态。 +- **C-34** 切换与回退以信箱处理标记交接(`OPS-4`、`PRE-1`):切回前,每条终态行都必须已打上处理标记。放弃自动重试的行没有标记,本系统写不出任何能阻止旧系统消费它的状态:须先人工恢复重试至打标,或与库方另行定处置(`Q9`),否则切回后这些行会被旧系统再处理。已登记、未到处理完成的消息同样没有交接状态。 待确认:在途消息的回退处置(`Q21`)。 ### 2.2 上游(AODB / SIS) - **C-20** 业务身份由 `SNDR`、`TYPE`、`STYP`、`SEQN` 组成,语义由上游定义,取值范围与回绕以 [SIS 接口规范](legacy/SIS_AODB_RMS-V0.1.md) 为准;`SEQN` 的重置周期未知,它决定身份是否加入日期边界。`(待确认 Q11)` - **C-21** `FLID` 在保留期内不复用;复用会让「只进不退」的合并把新航班的事件压掉。`(待确认 Q16)` -- **C-23** 应答到达时按报文类型对应到等待中的请求;AODB 发错或迟到的应答不更新数据,记录后跳过(`US-09` AC2)。`SCHD-RESP` 只在请求未过期时生效,迟到的应答不更新数据(`US-07`)。 +- **C-23** 应答到达时按报文类型对应到等待中的请求;AODB 发错、迟到(含过期的 `SCHD-RESP`,`US-07`)的应答一律不更新数据,记录后跳过(`US-09` AC2)。 待确认:用哪些字段对应、超时如何判定(`Q5`)。 -- **C-24** 出站信箱 `COUTMSGS`:消费方是 CIIMS adapter。`RQRD` 与 `RQFD` 各自同时最多一条已落信、未结案的请求;同一子类型发新请求时旧请求作废,新请求登记为待发送,等该报文类型的在途请求收到应答、失败或超时后再落信;请求超过时限未等到应答标记超时(`US-09` AC1)。收到 `EROR` 时定位到本系统发出的请求,标记失败并告警(`US-09` AC3)。重试只针对仍有效且确认未落信的请求;写入结果不明时记录并告警,不直接重发;交付承诺只到落信(架构「主流程」)。结案只有三种:应答到达且数据处理成功、超时、`EROR` 失败;未结案的在途请求占住同类的落信名额。 +- **C-24** 出站信箱 `COUTMSGS`:消费方是 CIIMS adapter。名额:`RQRD` 与 `RQFD` 各自同时最多一条已落信、未结案的请求,未结案的在途请求占住同类的落信名额。落信与结案:同一子类型发新请求时旧请求作废,新请求登记为待发送,等该报文类型的在途请求收到应答、失败或超时后再落信;请求超过时限未等到应答标记超时(`US-09` AC1);收到 `EROR` 时定位到本系统发出的请求,标记失败并告警(`US-09` AC3);结案只有应答处理成功、超时、`EROR` 失败三种。重试与交付:重试只针对仍有效且确认未落信的请求,写入结果不明时记录并告警、不直接重发;交付承诺止于落信(架构「主流程」)。 待确认:ACK 与错误列的语义及写入责任、出站行的清除与保留期、重复落信的识别规则、作废请求的范围(未落信直接撤销,已落信的如何结案)及其应答是否仍更新数据、写入结果不明的请求如何释放名额(`Q10`)。 -- **C-25** 删除主航班时级联删除其共享航班,原子提交、不删一半(`US-06` AC2)。本系统不向 AODB 回发 `EROR`:出站只有 `RQRD` 与 `RQFD`(架构「系统定位与范围」)。这是对 `SIS:1.6.5` 的正式例外——SIS 要求共享航班先删、主航班后删,顺序错乱时 RMS 向 AODB 回发 `EROR`;本系统级联删除不依赖该顺序,异常经告警暴露(`Q14`)。 +- **C-25** 删除主航班时级联删除其共享航班,原子提交、不删一半(`US-06` AC2)。本系统不向 AODB 回发 `EROR`:出站只有 `RQRD` 与 `RQFD`(架构「系统定位与范围」)。这是对 `SIS:1.6.5`(共享航班先删、主航班后删,顺序错乱时 RMS 向 AODB 回发 `EROR`)的正式例外,级联删除不依赖该顺序,异常经告警暴露(`Q14` 已定案)。 - **C-26** 日计划快照里没有携带的字段视为 AODB 已删除该值,本地同步清除(`US-07` AC3)。 -- **C-27** 五类资源分配报文(柜台 `CKDT`、转盘 `CLDT`、滑槽 `CHDT`、登机门 `GTDT`、机位 `PSDT`;`SIS:3.24`、`SIS:3.25`、`SIS:3.26`、`SIS:3.34`、`SIS:3.38`)在 SIS 中方向为 RMS→AODB,且标注 AODB 发来时 RMS 拒收;现场已定案照常接收处理(`US-05` AC3),这是对 SIS 的正式例外,与 AODB 的核对确认是实施前提。 +- **C-27** 五类资源分配报文(柜台 `CKDT`、转盘 `CLDT`、滑槽 `CHDT`、登机门 `GTDT`、机位 `PSDT`;`SIS:3.24`、`SIS:3.25`、`SIS:3.26`、`SIS:3.34`、`SIS:3.38`)在 SIS 中方向为 RMS→AODB,且标注 AODB 发来时 RMS 拒收;现场已定案照常接收处理(`US-05` AC3),是对 SIS 的正式例外。 + 待确认:与 AODB 的核对确认(`US-05` AC3 实施前提)。 ### 2.3 HTTP 入口 @@ -75,7 +79,7 @@ - **C-33** `POST /schd/sync` 触发一次 `RQFD` 日计划请求;成功响应无论表示已登记还是已落信,都不代表 AODB 已收到,交付承诺止于落信(`C-24`)。 待确认:成功响应表示已登记还是已落信(`Q17`)。 -### 2.4 下游(admin-api 与运营航班显示界面) +### 2.4 下游(admin-api、网页客户端与运营航班显示界面) - **C-29** 对外投递按至少一次设计,不承诺端到端恰好一次:应用重启与待发事件重发都可能让同一条消息多发一次。主题 `msg` 上同一 `FLID` 的变更保序,跨 `FLID` 不承诺顺序;`schd` 不在本条保序范围内。 待确认:Kafka key 与分区规则(`Q4`)。 @@ -85,10 +89,10 @@ ### 2.5 已作废条款 -- **C-1** ID 单调:信箱 ID 按提交顺序分配,已发布水位之下不再出现更小的新 ID。`[待确认 Q2]` **[作废 by C-30]** +- **C-1** ID 单调:信箱 ID 按提交顺序分配,已发布水位之下不再出现更小的新 ID。`(待确认 Q2)` **[作废 by C-30]** - **C-2** ID 分配 → 事务可见时延上界由库方**直接给出**。该值决定空洞老化阈值;**不可由 SIS 报文 `Expiry` 推导**(`Expiry` 是报文保留与传输恢复口径,与「ID 分配后多久对读事务可见」不是同一个量)。**[作废 by C-30]** - **C-11** 原文保留期是否沿用旧系统的 1 天窗口待确认;无论取何值都必须满足 `C-7` 的下界。`(待确认 Q9)` **[作废 by C-6]** -- **C-13** 只读约定区间的信箱行(`ID > W`),单活动实例运行,不引入并行消费者。`[我们单方承诺]` **[作废 by C-30]** +- **C-13** 只读约定区间的信箱行(`ID > W`),单活动实例运行,不引入并行消费者。`(本系统单方承诺)` **[作废 by C-30]** - **C-22** 报文不可变,见 `C-4`。`(待确认 Q15)` **[作废 by C-4]** ## 3. 前提 @@ -166,7 +170,7 @@ | CLM-4 | 信箱行最终都被写上处理标记 | `INV-7`、`C-15`、`C-16` | 不能 | 一直写不上的行留案并告警(`US-10` AC2) | | 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-8 | 出站交付承诺止于落信 | `C-24` | 能 | 只覆盖落信;ACK 与错误列语义未确认(`Q10`) | | CLM-9 | 消息将在某个时限内完成处理 | — | 不能 | 处理标记的写入时刻不是完成时限:扫描周期、批次积压与单行重试都会延长实际延迟 | | CLM-10 | 容量与吞吐量级 | — | 不能 | 无实测数据,取得信箱日量、峰值与单报文上限后重估 | | CLM-11 | 配置不完整时拒绝启动;「双实例同时启动只允许一个处理」无系统侧机制承载 | `OPS-1`、`PRE-5` | 启动拒绝能;双实例验收不能 | 运行时跨实例互斥不在此版设计内——不引入并行主泵或分布式锁是非目标(requirements「范围与非目标」),单实例靠部署保证(`PRE-5`);达成方式待 `Q29` |