- Kafka「尚需确定」去掉消费者去重与版本标识,改为消费方的字段要求 - `schd` 落定内容(`SCHD.FLTR` JSON,空字段不输出)、删除不进本主题、批次边界为定时 tick - `Q1` 收窄为 record 粒度(`C-9` 每条一条 vs 旧系统整批一个数组) - `Q5` 由版本标识改为 `msg` 的字段、编码与删除区分 - 删除航班版本号表述:README 事实归属的 `STATE_VERSION`、契约 `FLIGHT_SCHD` 的版本字段、验证映射 `INV-4` - 删除 requirements 的「本版本主要新增能力」changelog 句
19 KiB
19 KiB
规范:术语、约定、前提、不变量与能力边界
本文整理 msgexchange-v2 对外接口约定(C-x)、前提条件(PRE-x)、系统不变量(INV-x)、能力边界(CLM-x)、待确认事项(Qn)与已知偏差(G-NAME),并统一给出术语。条款依据 requirements.md 与 architecture.md 编写;字段联调草案另见 contracts/interface-contract.md,对外承诺以本文件为准。
C-x、PRE-x、INV-x、CLM-x、Qn、G-NAME 只在本文件定义,编号规则见 README.md。
约定条目的标记:
- 需要对方确认的,末尾标
(待确认 Qn)。 - 内容已定、个别字段未定的,另起一行以「待确认:」列出并指向
Qn。 - 本系统单方遵守、不依赖对方认可的,末尾标
(本系统单方承诺)。 - 未标注的,表示需求或架构已定,本系统按此执行。
1. 术语
| 术语 | 含义 |
|---|---|
| 上游 | 产生报文的 AODB,报文经 CIIMS adapter 写入信箱。 |
| 信箱 | 共享 MySQL 的 CMINMSGS(入站)与 COUTMSGS(出站),归库方所有;边界见 C-2。 |
| 库方 | 信箱所在的共享 MySQL 管理方,即 CIIMS adapter 方。 |
| 处理标记 | 即信箱行上的处理时间:为空表示未处理,处理完成时写入完成时刻。 |
| 落信 | 报文写入信箱成为一行;入站由 CIIMS adapter 或兼容入口写入,出站由本系统写入 COUTMSGS;入站报文写进信箱后可能尚未登记。 |
| 登记 | 本系统在自有 PG 为这条报文建立处理记录,排队等待处理。 |
| 处理完成 | 这条消息的结果已经确定——业务改动生效,或明确跳过、进入死信;之后才回填信箱标记、发 Kafka。 |
| 回填 | 处理完成后,把完成时刻写回信箱行的处理时间字段,告知上游该消息已处理。 |
| 投递 | 读待发事件,发往 Kafka。 |
| Redis 投影 | 供网页客户端(GET /all/flights)查询的航班投影,内容来自自有 PG 当前态;读写边界见 INV-11。 |
| 自有 PG | 本系统唯一的业务数据库;航班当前态、管道记录与静态参考数据都在这里。 |
| 权威 | 航班当前态以自有 PG 为准(INV-5)。 |
| 出站请求 | 经 COUTMSGS 发向 AODB 的 RQRD 参考数据请求与 RQFD 日计划请求,消费方为 CIIMS adapter。 |
| 运营航班显示界面 | 需求所称网页客户端:Kafka 侧称运营航班显示界面,查询侧称网页客户端(GET /all/flights / Redis)。 |
| 航班历史 | 已结束航班写入 Elasticsearch 后的副本;写成功后才从实时数据删除。 |
| 静态参考数据 | 13 类基础数据与资源状态,写自有 PG 的独立数据表,admin-api 直接只读。 |
2. 约定
2.1 共享信箱(库方)
- C-1 本系统清理已处理的入站信箱行(MySQL
CMINMSGS):回填完成且超过保留期后才删;保留期可配置,按约 1 个月(Q9)。处理未完成或回填未完成的行不删。 - C-2 共享 MySQL 不做 Schema 变更,本系统只读写
CMINMSGS与COUTMSGS两张表。
2.2 上游(AODB / SIS)
- C-3 业务身份由
SNDR、TYPE、STYP、SEQN四字段组合;SEQN自增,极少重置(消息服务器重启),重置后不会与旧消息冲突。 - C-4 出站请求写入
COUTMSGS;交付承诺止于落信。编码:SNDR=OMMS;SEQN本系统自建序列;DTTM北京时间YYYYMMDDHHMMSS;RQRD子类型以 SIS 为准共 14 类;RQFD为STYP=NONE,全量同步不带STDB/STDE等筛选(Q13)。 - C-5 航班删除为标记删除,主航班与共享航班各自独立标记。
- C-6 日计划快照里没有携带的字段视为 AODB 已删除该值,本地同步清除(
US-07AC3)。
2.3 HTTP 入口
- C-7
POST /cminmsgs/send:把 XML 写进入站信箱,与 adapter 投递走同一套处理。成功返回消息编号(仅表示已入库、未处理);失败不返回编号。支持text/xml、application/xml、text/plain(UTF-8);空、超长、格式错的不写;解析不拉外部资源。内网,访问由网络配置控制。仅内部联调;长度上限与失败响应实现时自定(Q15)。 - C-8
POST /schd/sync:向出站表写入一条日计划请求。 待确认:请求参数、HTTP 响应(Q16)。
2.4 下游(admin-api、网页客户端与运营航班显示界面)
- C-9 航班变更发到 Kafka 主题
msg(单条)和schd(批量);schd的内容是SCHD.FLTR序列化出的 JSON,空字段不输出,边界是定时任务的一次 tick——两次 tick 之间积累的变化整批发一次,没有变化就不发;删除航班不进schd,只由msg发一条删除通知;不设消息键。同一条可能发多次。 - C-10 静态参考数据写入本系统数据库,供 admin-api 只读;本系统不调用 admin-api。
- C-11 航班投影写入 Redis,供读取全体动态航班;
GET /all/flights与网页客户端读同一份;返回 JSON 由消息文档中的 XML 结构转换而来(Q6、Q21)。
3. 前提
前提失效时不变量必须整体重估。
| 编号 | 前提 | 若不成立的影响 | 状态 |
|---|---|---|---|
| PRE-1 | 测试环境与生产隔离:独立的数据库、Redis 与 Kafka 主题,不连接生产信箱 | 测试结论与隔离验收(OPS-3)失效 |
部署与配置约束 |
4. 不变量
4.1 管道
- INV-1 处理时间仍为空的信箱行会登记到本地;同一编号只登记一次。重扫或重启不会重复登记,也不会漏掉未登记的行。
- INV-2 只有本地处理结束后,才写信箱里的处理时间;本地记「已结束」时,必须同时记下还要去更新信箱,两笔记在同一次写入里。
- INV-3 航班增量与删除:改状态和记「待发 Kafka」同一次写入;记「已结束」和「还要更新信箱」另一次写入,且须在 Redis 写成功之后。处理未结束前不发 Kafka(
US-03AC4)。日计划与静态参考数据见架构「主流程」。 - INV-4 日计划整份报文校验不过时,本地航班数据一律不改(
US-07AC1)。
4.2 航班域
- INV-5 航班当前态只以自有 PG 为准;信箱、Redis、Kafka、展示视图都不是。
- INV-6
FLID唯一。 - INV-7 日计划:快照里没有的航班标记删除、登记删除事件并从 Redis 去掉;报文没带的字段本地清掉(
US-07AC2/AC3)。 - INV-8 航班标成已删除后,要从 Redis 去掉;去掉成功才算这条消息处理完(
US-06AC1)。 - INV-9 日计划可以分批写库,但整份写完并且 Redis 按这份结果刷完,才算处理完;失败就整份重来(
US-07AC4/AC5)。
4.3 Redis 投影
- INV-10 Redis 写成功,这条消息才算处理完;写失败就还没处理完,不回填、不发 Kafka,下轮再写(
US-05AC4)。本地已经写进库的,不因为 Redis 失败而撤掉(US-03AC3)。 - INV-11 Redis 航班投影只由本系统维护;查询与网页客户端读同一份;Redis 异常时报错,不交空列表(
US-12)。
5. 声明边界
| 编号 | 承诺 | 依赖 | 现在能否作出 | 限制或原因 |
|---|---|---|---|---|
| CLM-1 | 同一消息再处理不会多出一份业务效果 | US-03 |
不能 | 各类报文的细则未补齐(G-FLOP-IDEMPOTENT) |
| CLM-2 | 按信箱编号升序处理 | US-03 AC1 |
能 | — |
| CLM-3 | 主题 msg 上同一 FLID 内按发送顺序保序 |
US-08 AC2、C-9 |
能 | msg 单分区;至少一次重发时消费者仍可能见到乱序 |
| CLM-4 | 出站请求写入共享出站表 COUTMSGS |
C-4 |
能 | 只保证写入信箱,不保证 AODB 收到 |
| CLM-5 | 消息在固定时限内处理完 | — | 不能 | 需求未定完成时限;现场一般为即时处理,但不作时限保证 |
| CLM-6 | 容量与吞吐量级 | — | 不能 | 现场量级暂无;有日量、峰值等数据后再估 |
| CLM-7 | 配置不完整时拒绝启动 | OPS-1 |
能 | — |
6. 待确认事项台账
6.1 待对方确认
| 编号 | 事项 | 当前假定 | 影响 |
|---|---|---|---|
| Q1 | schd 的 Kafka record 粒度 |
按 C-9 是每条 record 一条运营航班 JSON;旧系统相反,把两次定时 tick 之间积累的整批序列化成一个 JSON 数组作为单条 record 发出 |
消费方的解析方式与 C-9 二者只能取一 |
| Q2 | 请求与应答按时间匹配时的时钟偏斜容忍判据 | 比较前统一时区与单位(implementation.md「上游请求与静态数据」) | 容忍判据未定前,降级匹配不得描述为精确关联 |
| Q3 | 现场会发但 SIS 未定义的子类型(靠桥、延误等)的报文形态与逐类终态 | 按现有处理逻辑延续,不得因 SIS 未记载就丢掉(US-05 AC1) |
逐类终态与幂等规则未定(G-FLOP-SEMANTICS) |
| Q4 | 上游重发时是否可能改发正文 | 报文不可变,绑定身份后不比对内容(implementation.md「消息、身份与决策」) | 改发正文的重发会被判为重复并跳过 |
| Q5 | msg 的 value 字段与类型、编码方式、变更与删除的区分方式 |
沿用旧系统:value 是 MSG 的 JSON(META 加对应业务体),日计划到达通知只有 META(接口契约「Kafka」) |
消费方读取契约无法定稿 |
| Q6 | 网页客户端读取 Redis 投影的约定 | 沿用旧系统的 hash flightInfo:field 为 FLID,value 为完整航班对象的带类型 JSON,不设过期;写入与移除时机见 INV-7、INV-8、INV-10;派生字段 MAFL、abdg 是否随投影提供仍未定;只作查询、不是权威;与 GET /all/flights 同一份(C-11;接口契约「Redis:航班查询投影」) |
消费方读取契约无法定稿 |
答复就地更新结论,并按 README.md「维护清单」落到对应条款。
6.2 已确认
| 编号 | 事项 | 结论 |
|---|---|---|
| Q7 | 信箱编号的单调、不复用、不回退 | 已定案:编号即入库行号,单调递增、不复用、不回退;按编号升序处理即按到达顺序(US-01 AC3、CLM-2) |
| Q8 | 入站处理时间列 | 已定案:与旧系统相同,列名为 CMINMSGS_DATE_PROCESSED;空为未处理,回填写入完成时刻(US-10) |
| Q9 | 入站信箱行(MySQL CMINMSGS)清除 |
已定案:本系统回填后自清(C-1);保留期可配置,按约 1 个月 |
| Q10 | 上游 SEQN 的重置周期与身份是否加日期边界 |
已定案:SEQN 自增,极少重置,重置后不与旧消息冲突,不加日期边界(C-3) |
| Q11 | 日计划未携带字段的删除语义 | 见 C-6 |
| Q12 | 主/共享删除顺序 | 已定案:标记删除,各自独立(C-5) |
| Q13 | RQRD / RQFD 编码字段 |
已定案:SNDR=OMMS;SEQN 本系统自建序列;DTTM 为北京时间 YYYYMMDDHHMMSS(SIS META);RQRD 子类型以 SIS 为准共 14 类(含 RSTA,其可选 RTYP);RQFD 的 STYP=NONE,STDB/STDE 等筛选可选,全量同步不带筛选(SIS:无参数则返回当天全部,对齐 US-07)(C-4) |
6.3 本系统与需求方待决
以下事项不出自对接方,由本系统与需求方决定:
| 编号 | 事项 | 当前假定 | 影响 |
|---|---|---|---|
| Q14 | 生产库选型 | 自有 PG 是唯一权威;生产环境用 PostgreSQL 还是 Oracle 11g 不能从三份依据确定,Oracle 适配验证通过前不作支持承诺 | 生产部署验收 |
| Q15 | POST /cminmsgs/send 的长度上限与失败响应 |
仅内部联调、无外部引用;成功返回编号等行为见 C-7;上限与失败格式现阶段不定,实现时在代码里自定 |
不阻塞对外契约 |
| Q16 | POST /schd/sync 的请求字段与时间格式、成功响应表示已登记还是已落信、状态码与错误响应 |
交付承诺止于落信(C-4);旧系统线索为 {startDate, endDate} 与 12 小时制时间(接口契约「HTTP」) |
响应契约无法定稿(C-8) |
| Q17 | 人工发起 RQRD 的方式 |
US-09 要求人工发起,HTTP 接口清单没有对应入口 |
参考数据请求无法人工触发 |
| Q18 | 回退时在途消息(已提交业务变更、未到处理完成)的处置 | 回填了结后切换(OPS-4);在途消息无跨系统幂等保障 |
回退演练的验收口径(OPS-4) |
| Q19 | 是否在自有 PG 留存入站原文副本,及原文提前清除时已登记消息的处置 | 不留存,原文只从信箱读取 | 提前清除的消息不可恢复,处置未定 |
| Q20 | 日计划中运营日冲突的处置 | 未定 | 冲突场景无法验收 |
| Q21 | GET /all/flights 的状态码、错误响应样例、外层包装是否沿用旧 ResponseDto |
返回体是消息文档中的 XML 结构转换出的 JSON;读 Redis、返回全体动态航班、不分页(C-11) |
查询契约无法定稿 |
| Q22 | REF_MASTER 的物理列、唯一键、空值存储与写入后可见时点 |
记录用类别码加识别标签识别(接口契约「静态参考数据类别与编号来源」) | admin-api 读取契约无法定稿(C-10) |
| Q23 | Elasticsearch 历史索引、文档 ID、字段映射、成功判据、保留期与容量上限、写入结果不明的对账与幂等策略 | 历史写入确认成功才删实时数据(D1、US-14 AC3) |
历史链路无法验收(US-14;G-FLIGHT-HIST-RETENTION) |
| Q24 | REQ_TRACK 已结案记录的保留期取值 |
到期清理没有可依据的窗口(G-REQ-TRACK-RETENTION) |
请求历史清理无法实现(US-09) |
| Q25 | 季度计划的数据来源与归属:admin-api 从本系统库读季度计划,而 SIS 只有日计划事件(SIS:3.16、SIS:3.17、SIS:4.7) |
应由 AODB 下发,报文形态待确认;旧系统读 Oracle 的 FIMS_FLIGHTSCHD_SEASON |
admin-api 的季度计划查询没有供数方 |
7. 当前已知偏差
本表是偏差标记的唯一出处,其他文档只写 G-NAME。闭合时删除本行与全仓引用。
| 偏差 | 缺什么,会怎样 | 影响 |
|---|---|---|
G-REQ-TRACK |
出站请求没有跟踪:登记、编码、超时与应答匹配都没有实现 | US-09 |
G-REQ-OPEN-UNIQUE |
同一报文类型同时最多一条已落信、未结案请求的限制没有实现;待发送登记不算占用该名额 | US-09 |
G-REQ-TRACK-RETENTION |
REQ_TRACK 已结案记录的保留期取值未定,到期清理作业没有可依据的窗口(取值待 Q24) |
US-09 |
G-FLIGHT-HIST-RETENTION |
历史存储的保留期与容量上限未定(取值待 Q23) |
US-14;实时数据删除后历史是唯一副本 |
G-FLOP-IDEMPOTENT |
逐类幂等规则未补齐 | US-03;CLM-1 |
G-FLOP-SEMANTICS |
STYP 没有白名单,ROUT 未限制 4 条,运行状态落点与已删除航班的处理与 US-05 不符 |
US-05 |
G-FLOP-UNMAPPED |
XSD「FLOP 元素」里有些字段没有解码或映射错了,会被静默丢掉 | US-05 |
G-MAFL |
主航班的共享航班列表未实现 | US-06 AC2;C-5 |
G-SRVT-VIPF |
SRVT、VIPF 两个集合没有落到持久化明细 |
US-05 |
G-SCAN-PREDICATE |
收报仍按水位扫描,不是按「处理时间为空」读取 | US-01;INV-1 |
G-REDIS-PROJECTION |
Redis 投影没有写入与移除路径 | US-05、US-06、US-07、US-12 |
G-SCHD-SNAPSHOT |
日计划快照不删除缺席航班、不清除未携带字段,也没有分批;逐航班重写幂等未补齐 | INV-7;INV-3;INV-9 |
G-PROC-CLEANUP |
处理记录的到期清理作业未实现 | US-11 |
G-REF-DATA |
静态参考数据没有处理,当前按「合法但不支持」跳过并回填;参考数据表与 admin-api 直读未落地 | US-13;US-03 |
8. 验证映射
| 不变量 | 需求验收 | 要观察的结果 |
|---|---|---|
| INV-1 | US-01 AC1/AC2/AC4 |
扫描重来与重启后登记数不变、行不丢;同一编号重复出现时处理记录数不增加 |
| INV-1、C-7 | US-02 AC1~AC5 |
兼容入口接受三种媒体类型、默认 UTF-8;空报文、超上限、非法 XML 不落信并返回错误,解析禁用外部实体与外部资源;成功返回编号且只表示落信;内网来源由网络层配置核对;写入的行与上游投递同路径被发现、登记 |
| CLM-2 | US-01 AC3、US-03 AC1 |
按编号升序处理;队头未完成时后面的消息不被处理 |
| US-03 AC2/AC5 | US-03 AC2/AC5 |
死信与跳过留档且无业务副作用;错误在对应处理记录上可查 |
| US-03 AC3 | US-03 AC3 |
失败回滚后消息仍在未完成;已提交结果不被写信箱处理时间或发 Kafka 失败回滚 |
| INV-2 | US-10 AC1/AC2 |
终态后才回填;重启后继续,写不上的有记录与告警 |
| C-9 | US-08 AC1/AC2/AC3 |
msg 单条变更、schd 批量;失败重试后仍能投出;一直失败的记录保留可查并告警;msg 同一 FLID 按发送顺序保序(CLM-3);同一条可能多发(C-9) |
| INV-5 | 架构「系统定位与范围」 | 航班当前态的权威写入只在自有 PG |
| INV-6 | 架构「必须保持的约束」 | FLID 唯一 |
| US-04 AC2 | US-04 AC2 |
未携带的字段保持原值 |
| INV-7 | US-07 AC2/AC3 |
缺席的航班在 PG 标为已删除并从 Redis 投影移除;未携带的字段被清空 |
| INV-3 | US-03 AC4、US-05 AC4、US-06 AC1 |
投影写失败时,没有终态与回填意图落库;处理完成前事件不可投递 |
| US-14 AC4 | US-14 AC4 |
历史清理跳过正在被消息处理的航班 |
| INV-4 | US-07 AC1 |
校验失败后本地数据不变 |
| INV-9 | US-07 AC4/AC5 |
分批失败后整包重处理收敛到同一目标(G-SCHD-SNAPSHOT 闭合前无法验证);Redis 在整包写入完成后按快照刷新,成功即与快照一致 |
| CLM-1 | US-03 |
同一消息不产生两次效果;逐子类型规则与幂等矩阵在 Q3、G-FLOP-IDEMPOTENT、G-FLOP-SEMANTICS 闭合前无法验证 |
| INV-8 | US-06 AC1 |
航班标记删除后从投影移除;移除失败时下轮重做 |
| US-14、D1 | US-14 AC3 |
历史写入成功才删实时数据;删除事件在实时数据删除前登记(D1) |
| US-06 AC2 | US-06 AC2 |
删共享联动主航班;删主航班级联删共享 |
| INV-10 | US-05 AC4、US-06 AC1 |
投影写失败的消息下轮仍被处理 |
| INV-11 | US-12 AC1/AC2 |
返回全部非共享航班,且与 Redis 一致;Redis 故障时返回错误 |
| US-11 | US-11 AC1/AC2 |
未完成的记录不被删除 |
| US-13 | US-13 AC1~AC5 |
全量整体替换、增删改逐条;空值是「没有值」不是删除;一类校验失败只停该类;参考数据落独立表供 admin-api 只读(C-10) |
| US-10 AC2 | US-10 AC2 |
写失败重试与告警可观测 |
| CLM-4 | US-09 AC1~AC3 |
出站请求写入 COUTMSGS |
| CLM-5(不承诺完成时限) | — | 需求未定完成时限;现场一般为即时处理 |
| CLM-6(容量) | — | 现场量级暂无;有数据后再估 |
| OPS-4 | OPS-4 |
回退演练:回填了结后切回,旧系统不重处理已产生业务效果的消息;在途窗口处置见 Q18 |
| CLM-7 | OPS-1 |
配置错误启动失败测试可验收 |
| PRE-1(测试隔离) | OPS-3 |
测试环境配置核对:独立的数据库、Redis 与 Kafka 主题,不连接生产信箱 |