docs: 统一术语、收紧需求验收范围、修正 Q3 归属

- "自有业务数据库" → "自有 PG",与 specification/architecture 统一
- US-05 AC1 钉死现场 7 类子类型,白名单其余待 Q3 确认后增补
- US-05 AC3 恢复未映射字段唯一键(信箱编号+路径+出现序号)
- US-09 AC1 恢复旧请求作废可观察约束
- implementation.md VIPP/未映射字段去掉误引 Q3(不在 Q3 范围)
- 精简 architecture/requirements 系统定位复述与实现机制泄漏
This commit is contained in:
windyboy
2026-09-20 09:30:01 +08:00
parent 8749d83d83
commit f3b791712b
8 changed files with 43 additions and 88 deletions
+2 -2
View File
@@ -106,7 +106,7 @@ docker compose ps
### 切流前 Kafka Broker 版本确认
生产契约以 [requirements.md](docs/requirements.md) `US-08``D2` 为准(三项生产者约束的取值见 [reference.md](docs/reference.md) 参数表),**严禁非幂等降级**。README 不提供生产降级环境变量组合
投递顺序须满足 [requirements.md](docs/requirements.md) `US-08``D2`;当前生产者配置见 [reference.md](docs/reference.md)「信箱与外部依赖(成组登记)」,启动自检会校验。**严禁非幂等降级**
旧系统 `msgexchange-api` 底层依赖 `kafka-clients:0.10.1.1`;现网 Broker 确切版本须在切流前实测确认:
@@ -114,7 +114,7 @@ docker compose ps
```bash
docker exec msgx-dev-kafka /opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server <TARGET_IP>:9092
```
2. **门禁判定**:若输出中 `InitProducerId(22)` 为 **可用** → 保持 `D2` 的高可靠默认
2. **门禁判定**:若输出中 `InitProducerId(22)` 为 **可用** → 使用当前生产者配置
3. **阻塞切流**:若 `InitProducerId(22)` 为 **UNSUPPORTED**Broker &lt; 0.11)→ **阻塞切流**,须升级 Broker 或经架构豁免(ACM2-1 基础设施升级门禁);降级参数仅可作为经批准的 runbook 附录,**不得**作为生产验收口径与 README 默认配置并存。
## 构建
+1 -1
View File
@@ -75,5 +75,5 @@
## 6. 不建的文件
- 顶层不再增加 Markdown`docs/` 顶层固定为上述 6 个文件加允许的专题目录。
- 不建运行规程文件:设计阶段没有可执行的运行环境,操作步骤在上线/切流前另立(`docs/runbooks/*.md`);设计阶段需要的只有前置条件与红线,它们分别在 specification.md「前提」与 architecture.md「必须保持的约束」、specification.md 的 `CLM-x`
- 不建运行规程文件:设计阶段没有可执行的运行环境,操作步骤在上线/切流前另立(`docs/runbooks/*.md`);设计阶段前置条件与红线 specification.md 的 `PRE-x`、`INV-x`、`CLM-x` 和 architecture.md 的 `D1``D2` 承载
- 声明边界与 Plane 分离:未交付、未确认、不可声明的主张记在 specification.md,逐项处置在 Plane(ACM2),不在正文逐段标注。
+15 -46
View File
@@ -4,17 +4,7 @@
## 1. 系统定位与范围
msgexchange-v2 替换旧版 `msgexchange-api` OMMS H5 查询系统的消息网关。
功能需求是 [requirements.md](requirements.md) 的十四条用户故事(采集、处理、投递、查询、维护,`US-01``US-14`),运行需求是四条验收(单实例、可观测、测试隔离、切换回退,`OPS-1``OPS-4`);完整非目标见同文件「范围与非目标」。
- **主要入口**:轮询共享 MySQL 入站表 `CMINMSGS`,只取处理时间为空的行,按编号升序、每批有上限(`US-01``INV-1`)。
- **兼容入口**`POST /cminmsgs/send` 供联调工具把报文写进信箱,与上游投递走同一条处理路径;返回的编号只表示已进信箱,不代表已处理或下游已收到(`US-02`)。
- **查询入口**`GET /all/flights` 返回当前全部动态航班(不含共享航班),读 Redis,与网页客户端同源(`US-12``INV-11`)。
- **出站**:只向 AODB 发参考数据请求 `RQRD` 和日计划请求 `RQFD`,经共享 MySQL 出站表 `COUTMSGS`,由 CIIMS adapter 消费;只保证请求写入信箱,不保证 AODB 收到(`US-09``C-4`)。
- **输出**Kafka 主题 `msg` 发单条航班变更、`schd` 定时发批量最新状态;Redis 存航班投影;静态参考数据表供 admin-api 只读(`US-08``US-13`)。
- **权威**:航班当前态的权威是自有 PostgreSQL(`FLIGHT_SCHD`、资源明细表、`FLIGHT_ROUTE_POINT`);信箱、Redis、Kafka、展示视图都不是(`INV-5`)。
- **航班历史**:已结束航班先写入 Elasticsearch 历史库,成功后才从实时数据删除(`US-14``D1`)。
msgexchange-v2 替换旧版 `msgexchange-api`承接 OMMS H5 查询系统的消息网关职责
## 2. 总体架构
@@ -25,7 +15,7 @@ CIIMS adapter(把 AODB 下发的 XML 写入信箱)
共享 MySQLCMINMSGS(入站信箱)
──────── msgexchange-v2(单活动实例,同进程四组线程 ────────
──────── msgexchange-v2(单活动实例) ────────
ingress 收报 processing 处理(流程见「主流程」)
delivery 投递 jobs 作业:回填 / 出站重试 / 历史清理 / 记录清理
──────────────────────────────────────────────
@@ -37,11 +27,7 @@ delivery 投递 jobs 作业:回填 / 出站重试 / 历史清理 /
└─▶ 自有 PostgreSQL:航班当前态 / 管道与未映射字段记录 / 静态参考数据 ── admin-api 只读参考数据
```
四组线程在同一进程、互不调用,协作只经自有 PG 的持久记录交接;HTTP 接口走事件循环,不占这四组线程。重启后各段从记录接着做,不依赖内存进度`US-01` AC4、`US-03` AC3、`US-10` AC2)。
线程之间不加锁,靠幂等写入:收报按信箱编号只登记一次(`US-01` AC2)、回填只写空标记(`INV-2`)、记录清理只删已回填且超过保留期的行(`US-11`)。
运行边界:切换与回退以信箱处理标记交接,内部处理与回填进度保存在自有 PG 的 `PROC_STATE``OPS-4`)。
跨阶段的待办与处理进度持久化在自有 PG,重启后从记录继续`US-01` AC4、`US-03` AC3、`US-10` AC2)。
技术栈:Kotlin + JDK 25、Micronaut 编译期依赖注入、JDBC 持久化;数据库变更由 Flyway 管理,只作用于自有 PostgreSQL。依赖版本见 `build.gradle.kts`
@@ -52,8 +38,8 @@ delivery 投递 jobs 作业:回填 / 出站重试 / 历史清理 /
| `ingress` | 轮询信箱、登记入队、兼容入口落信(`US-01``US-02`);不解析业务报文。 |
| `codec` | XML 解码,区分非法报文与可修复的解码失败(`US-03`)。 |
| `processing` | FIFO 调度、业务身份绑定与去重、领域决策与落库(`SCHD`/`FLOP`/`FDEL`/`ADFT`/静态参考数据),航班类写 Redis 投影,未落到航班当前态的字段写 `UNMAPPED_FIELD`。 |
| `delivery` | 读待发事件投 Kafka:按 `FLID` 保序、`schd` 聚合、失败重试(`US-08``C-9`)。 |
| `jobs` | 回填扫描、出站请求重试、航班历史清理,以及 `PROC_STATE``MSG_EVENT``SCHD_SNAP_LOG``REQ_TRACK` 的到期清理;单独线程、不进 FIFO(与主泵的协作见 `US-14` AC4)。 |
| `delivery` | 读待发事件投 Kafka,聚合 `schd`失败重试(`US-08``C-9`)。 |
| `jobs` | 回填、出站重试、航班历史与到期记录清理;不占主泵 FIFO`US-10``US-11``US-14`)。 |
| `domain` / `config` | 领域状态、事件和决策模型,以及运行参数。 |
| `infra` | 仓储(JDBC/stub)、外部适配器(共享信箱、Kafka、Redis、航班历史存储、AODB 出站)、重试、健康检查与日志;对其他模块只暴露接口。 |
@@ -78,39 +64,22 @@ delivery 投递 jobs 作业:回填 / 出站重试 / 历史清理 /
| 出站请求 | 不走收报队列:登记新请求并作废同子类型旧请求;`RQRD``RQFD` 各自最多一条在途,后续请求待前一条结案再写入 `COUTMSGS` | 请求已写入信箱(`US-09` AC1 | `jobs``REQ_TRACK` 重试仍有效且确认未落信的请求;写入结果不明时记录并告警,不直接重发;交付承诺只到落信(`C-4` |
| 航班历史清理(作业) | 不走消息队列:历史写入成功后物理删除 | 实时数据已删(`US-14` AC3) | 历史写不成功不删,下轮重来(`US-14` AC3 |
## 5. 必须保持的约束
以下约束不得违反:
- 只跑一个实例;主泵写航班当前态,历史清理作物理删除;正在被消息处理的航班清理时跳过(`OPS-1``US-14` AC4)。
- 按顺序处理、只处理一次:每次只取编号最小的未完成消息(`US-03` AC1),重复扫描、失败重处理与兼容入口并发都只登记一次、生效一次(`INV-1`);不丢消息依赖「编号即到达顺序」且编号不复用、不回退(`Q7`)。
- Redis 写成功才算处理完成;查询接口与网页客户端读同一份 Redis,出问题时报错,不返回空列表假装正常(`INV-10``INV-11``US-05``US-06``US-12`)。
- 日计划快照以 AODB 下发为准:快照里没有的航班删除,未携带的字段清除;增量报文按携带字段更新、未携带的不清空(`INV-7``US-07``US-04` AC2)。
- 对外投递至少一次,跨航班不承诺顺序(`C-9``US-08`)。
- 航班只在历史写入成功后删除,历史库还没接通时一条也不删(`D1``US-14`)。
- 静态参考数据一类校验失败只停这一类,其他类照常;空值是「当前没有值」,不是删除(`US-13`)。
- 航班唯一:`FLID` 唯一(`INV-6`)。
这些约束是拿速度换来的:单活动主泵一次只推进一条,前一条没处理完,后面都得等。要提速、要多实例,光加线程没有用——得先重新设计消息顺序和数据由谁写,多实例还得补上可靠的互斥保护。
## 6. 数据归属与一致性
## 5. 数据归属与一致性
| 存储 | 承载内容 | 职责说明 |
|---|---|---|
| 自有 PostgreSQL | 处理锁 `PIPELINE_LOCK`消息处理状态回填意图 `PROC_STATE`、待发事件 `MSG_EVENT`、出站请求跟踪 `REQ_TRACK`、航班当前态 `FLIGHT_SCHD`、资源明细表、`FLIGHT_ROUTE_POINT`、未映射字段长期记录表 `UNMAPPED_FIELD`、静态参考数据表组(admin-api 实体对齐,`Q22`)、日计划快照留痕 `SCHD_SNAP_LOG` | 本系统唯一的业务数据库,也是航班当前态的唯一权威(`INV-5`);本地事务只发生在这里,事务怎么分段见「主流程」。`UNMAPPED_FIELD` 不随 `PROC_STATE` 到期清理。 |
| Redis | 航班查询投影 | 只作查询,不是权威,也不存处理状态(`INV-5`);只由本系统写入和移除(`INV-11`),内容来自 PG 当前态;`GET /all/flights` 与网页客户端读的就是它。 |
| 共享 MySQL | `CMINMSGS` 入站信箱、`COUTMSGS` 出站信箱 | 信箱归外部系统所有。本系统只读写消息、回写处理标记,不建表、不改表结构、不写历史表(`C-2`);已回填的入站行按保留期自清`C-1``Q9`)。出站请求写进去就算交付(`C-4`)。 |
| 航班历史存储(Elasticsearch | 已结束航班的历史副本 | 已结束航班写入这里作历史副本;写入确认成功后才删实时数据,写不成一条也不删(`D1``US-14` AC3)。保留期与容量上限未定(`G-FLIGHT-HIST-RETENTION`)。 |
| 自有 PostgreSQL | 消息处理状态回填意图、待发事件、出站请求状态、航班当前态、未映射字段与静态参考数据 | 航班当前态的唯一权威;本地事务只覆盖此库(`INV-5`。 |
| Redis | 航班查询投影 | 由本系统根据 PG 当前态维护;不存处理状态(`INV-11`。 |
| 共享 MySQL | 入站与出站信箱 | 外部邮箱边界;不改表结构,出站交付止于落信`C-2``C-4`)。 |
| Elasticsearch | 已结束航班的历史 | 历史写入成功后才删实时航班(`D1`)。 |
**PG 事务只管自己库。** Redis 写没写成、信箱标记写没写上、Kafka 发没发出,PG 事务都管不着;这些步骤各自可重试,重做多少遍结果都一样,重启后从 PG 记录接着走
跨存储步骤不能并入 PG 事务,由持久意图与幂等重试衔接;具体分段见「主流程」
对外投递只承诺至少一次(`C-9`):应用重启、待发事件重发都可能让同一条消息多发一次,Kafka 的生产端幂等挡不住这种重复。
## 6. 关键决策
## 7. 关键决策
只列正文推不出来、仍有约束价值的决策,按 `D1``D2` 编号。第三列只给证据与偏差指针;决策不随实现状态增删。
以下决策补充主流程的跨存储边界。
| 编号 | 决策及理由 | 证据 / 偏差 |
|---|---|---|
| D1 | 删除实时数据前,须已登记待发删除事件:FDEL 航班状态变更事务中登记,Redis 移除成功后才算处理完成;历史清理历史写入成功,必要时登记待发删除事件,再物理删除。历史写入是需求内交付(`US-14`)。 | `US-06` AC1、`US-14` AC3 |
| D2 | Kafka 生产端同时满足三项:确认级别、幂等、单连接在途条数上限;不许关幂等绕开这条限制。 | 保序目标见 `US-08` AC2 |
| D1 | FDEL 航班状态变更与待发删除事件同一事务提交;历史清理先确认历史写入成功,必要时登记待发删除事件,再物理删除。 | `US-06` AC1、`US-14` AC3 |
| D2 | `msg` 单分区投递;同一 `FLID` 按事件顺序发送,队头失败时暂停该航班的后续事件。生产端须保持发送顺序,重发可能重复。 | `US-08` AC2、`CLM-3``C-9` |
+4 -4
View File
@@ -31,7 +31,7 @@ AODB 经 CIIMS adapter 把 XML 报文写入 `CMINMSGS`,格式以架构指定
| 环节 | 已确定的边界 | 尚需确定 |
|---|---|---|
| 出站请求 | 本系统只发 `RQRD` 参考数据请求与 `RQFD` 日计划请求,经 `COUTMSGS` 落信,交付承诺止于落信(`US-09`;架构「系统定位与范围」「主流程」)。编码规则已定(`C-4`)。 | 超时的时限取值。 |
| 出站请求 | 本系统只发 `RQRD` 参考数据请求与 `RQFD` 日计划请求,经 `COUTMSGS` 落信,交付承诺止于落信(`US-09``C-4`)。 | 超时的时限取值。 |
| 在途与作废 | `RQRD``RQFD` 各自同时最多一条已落信、未结案的请求;同一子类型发新请求时旧请求作废,新请求登记为待发送,等该报文类型的在途请求收到应答、失败或超时后再落信;请求超过时限未等到应答标记超时(`US-09`)。 | 超时的时限取值。 |
| 应答匹配 | 应答按报文类型对应到等待中的请求;AODB 发错或迟到的应答不更新数据,记录后跳过(`US-09`);`SCHD-RESP` 只在请求未过期时生效,迟到的应答不更新数据(`US-07`)。 | 请求与应答的对应字段、过期判定的依据字段。 |
| 错误回报 | 收到 `EROR` 时定位到本系统发出的请求,标记失败并告警(`US-09`)。 | `EROR` 与请求的对应字段。 |
@@ -87,8 +87,8 @@ AODB 经 CIIMS adapter 把 XML 报文写入 `CMINMSGS`,格式以架构指定
| 表或表组 | 边界 | 尚需确定的字段级契约 |
|---|---|---|
| 静态参考数据表组 | 静态参考数据与资源状态保存在独立数据表组(逻辑视图 `REF_MASTER`,物理形态由内部迁移确定;报文到表的映射待 `Q22` 定稿;联调栈 `basicdata` schema 的基础数据表对齐 admin-api 实体注解,不预设 `REF_MASTER` 落表方式);表与列直接取 admin-api 实体注解,不改名、不合并,admin-api 直接只读;新消息覆盖旧记录,全量消息整体替换,增删改消息逐条处理(`US-13`);一类校验不通过只停这一类、其他类照常,校验失败类别的已有记录不变;字段为空表示「当前没有值」,不是删除(架构「必须保持的约束」)。 | 13 类报文与资源状态到表组的映射(`Q22`);admin-api 需要哪些字段。类别码与消息中的识别标签见下表。 |
| 航班当前态表 | 航班当前态的唯一权威;`FLID` 唯一(架构「必须保持的约束」);Redis 和 Kafka 从处理结果派生,不反向覆盖这些表。 | 主键、字段与类型、外键/索引。 |
| 静态参考数据表组 | 静态参考数据与资源状态保存在独立数据表组(逻辑视图 `REF_MASTER`,物理形态由内部迁移确定;报文到表的映射待 `Q22` 定稿;联调栈 `basicdata` schema 的基础数据表对齐 admin-api 实体注解,不预设 `REF_MASTER` 落表方式);表与列直接取 admin-api 实体注解,不改名、不合并,admin-api 直接只读;新消息覆盖旧记录,全量消息整体替换,增删改消息逐条处理(`US-13`);一类校验不通过只停这一类、其他类照常,校验失败类别的已有记录不变;字段为空表示「当前没有值」,不是删除(`US-13` AC4)。 | 13 类报文与资源状态到表组的映射(`Q22`);admin-api 需要哪些字段。类别码与消息中的识别标签见下表。 |
| 航班当前态表 | 航班当前态的唯一权威;`FLID` 唯一(`INV-6`);Redis 和 Kafka 从处理结果派生,不反向覆盖这些表。 | 主键、字段与类型、外键/索引。 |
| 内部处理表 | 管道处理、请求跟踪、留痕与互斥由本系统维护;不对外提供直接读写接口。 | 字段与约束由内部实现设计确定。 |
admin-api 还从本系统数据库只读季度计划;供数方与报文形态待 `Q25` 确定。
@@ -121,7 +121,7 @@ admin-api 还从本系统数据库只读季度计划;供数方与报文形态
| 契约项 | 已确定的边界 | 尚需确定 |
|---|---|---|
| 写入对象 | 满足 `US-14` 已结束判据的航班从自有业务数据库写入 Elasticsearch 历史库,作为历史查询副本。 | 历史索引名称、文档 ID、写入字段及类型、嵌套资源结构、字段缺失与删除状态的表达方式、索引保留期与容量上限(架构「数据归属与一致性」列为未定)。 |
| 写入对象 | 满足 `US-14` 已结束判据的航班从自有 PG 写入 Elasticsearch 历史库,作为历史查询副本。 | 历史索引名称、文档 ID、写入字段及类型、嵌套资源结构、字段缺失与删除状态的表达方式、索引保留期与容量上限(`G-FLIGHT-HIST-RETENTION`)。 |
| 成功确认 | 只有该航班的历史写入成功,才允许从实时数据物理删除;删除前按 `D1` 必要时登记待发删除事件。 | Elasticsearch 写入响应中何种结果算成功、成功是否要求可查询。 |
| 写入粒度 | 单个航班写入失败不影响其他航班。 | 部分成功时的确认与继续处理规则。 |
| 失败与重试 | 写入失败的航班保持在实时数据中,下次运行再试;已写入的航班不重复写入;正在被消息处理的航班跳过,下轮再处理。文档 ID 按旧系统线索为 `SODT + FLID` 幂等 upsert,写入结果不明时重试同一写入。 | 重试间隔。 |
+6 -6
View File
@@ -249,7 +249,7 @@ PENDING → SENT → DONE
发送确认后才标记 `SENT`,失败记录次数并按退避推后,达到上限转 `DEAD`(记录保留作 DLQ)。所有外部调用需要有界超时,避免阻塞投递线程。
投递是至少一次:Broker 或其他目标已接受但本地未标记成功时可能重发;目标端接受不等于业务消费者已消费。Kafka 生产约束沿用 `D2`生产者幂等不替代应用层事件去重。
投递是至少一次:Broker 或其他目标已接受但本地未标记成功时可能重发;目标端接受不等于业务消费者已消费。Kafka 生产端按 `D2` 保持顺序,当前配置见 [reference.md](reference.md)「信箱与外部依赖(成组登记)」;生产者幂等不替代应用层事件去重。
### 8.2 `schd` 聚合
@@ -466,17 +466,17 @@ FLOP 只修改报文表达的字段或集合,其余状态保持不变;目标
| `SIS:3.40` | `ROUT` | `ROUT` 集合 | `SCAT`/`SCDT` 分别对起点/终点缺席;RMS 只保留 4 条(离港取前 4、到港取后 4)且不保存 `SCAT`/`SCDT` |
| `SIS:3.41` | `TAOP` | `TAOP`/`TAFL`/`TAID` 标量 | 任一为空 = 该到达航班的经停连接断开 |
| `SIS:3.42` | `TRML` | `TRML` 标量 | 空 = 删除航站楼 |
| `SIS:3.43` | `VIPP` | `VIPP`/`VIPR` 标量 | 空 = 删除;SIS 另要求 RMS 忽略 `VIPP`(忽略事件还是忽略字段,SIS 未写明,`Q8` 对拍确认 |
| `SIS:3.43` | `VIPP` | `VIPP`/`VIPR` 标量 | 空 = 删除;SIS 另要求 RMS 忽略 `VIPP`(忽略事件还是忽略字段,SIS 未写明,须以真实报文确认,见 `G-FLOP-SEMANTICS` |
`CKDT``CLDT``CHDT``GTDT``PSDT` 等 FLOP 子类型是否入站、如何合并,见 `US-05` 与本章「动态运行事件」;SIS 中的 RMS→AODB 方向说明不约束本系统(OMMS 只收不发)。
**SIS 未定义但 legacy 处理的子类型**`ABTM``DELY``PADT``FTSS``STND``BDPB``REMC`。它们在 `XSD``FLOP` 段里是普通字段或集合,没有独立事件节;legacy 按 `STYP` 命中它们处理,说明真实流量可能存在 SIS 未记载的子类型。其报文形态与是否存在必须以真实报文确认(`Q8`),不得据 legacy 行为直接定案。
**SIS 未定义但 legacy 处理的子类型**`ABTM``DELY``PADT``FTSS``STND``BDPB``REMC`。它们在 `XSD``FLOP` 段里是普通字段或集合,没有独立事件节;legacy 按 `STYP` 命中它们处理,说明真实流量可能存在 SIS 未记载的子类型。其报文形态与是否存在必须以真实报文确认(`Q3`),不得据 legacy 行为直接定案。
**SIS 定义但 legacy 无处理器**`CHDT``FINT``MAXP`
**未映射字段**[XSD](legacy/unisysaodbsis.xsd)「FLOP 元素」中尚未解码或错误映射的字段见 `G-FLOP-UNMAPPED`;其中 `FRET``FDIV``BDPB` 在 legacy 有对应处理,逐项必须`Q8` 对拍时定案(补齐映射或明确声明忽略),不得静默丢弃。
**未映射字段**[XSD](legacy/unisysaodbsis.xsd)「FLOP 元素」中尚未解码或错误映射的字段见 `G-FLOP-UNMAPPED`;其中 `FRET``FDIV``BDPB` 在 legacy 有对应处理,逐项必须定案(补齐映射或明确声明忽略),不得静默丢弃。
动态事件保留既有 `OPERATION_DAY`,也不基于接收时间重新推导它。除 FDEL 外,SIS 未规定目标航班不存在或已删除时的结果;逐类终态必须经 `Q8` 定案,不能统一推定为成功。当前实现的白名单、`ROUT`、BOTM/LACL 状态与已删除航班行为偏差见 `G-FLOP-SEMANTICS`
动态事件保留既有 `OPERATION_DAY`,也不基于接收时间重新推导它。除 FDEL 外,SIS 未规定目标航班不存在或已删除时的结果;逐类终态必须经 `Q3` 定案,不能统一推定为成功。当前实现的白名单、`ROUT`、BOTM/LACL 状态与已删除航班行为偏差见 `G-FLOP-SEMANTICS`
### 12.3 删除与重建
@@ -559,5 +559,5 @@ SIS 声明的上游忽略与截断口径(`SIS:3.1`/`SIS:3.2`/`SIS:3.4`/`SIS:3.
- 数据方向固定为「SIS 消息 → 本网关 → 业务数据库 → admin-api」;本网关不调用 admin-api,不读取其数据库或缓存。
- admin-api 只读取已提交的航班状态与 `REF_MASTER` 有效视图,不参与消息解码、合并、批次发布或处理终态判定。
- 开发运行时使用自有 PostgreSQLOracle 只有通过 `Q1` 要求的方言与集成验证后才可替代,单次部署不得同时把两库作为权威。
- 开发运行时使用自有 PostgreSQLOracle 只有通过 `Q14` 要求的方言与集成验证后才可替代,单次部署不得同时把两库作为权威。
- admin-api 直接读取本系统写入的静态参考数据表(`C-10`);共享 MySQL 始终只是信箱边界,不承载该读取模型。
+5 -5
View File
@@ -6,7 +6,7 @@
## 1. 参数注册表
「依据」列含义:**契约** = 由 [specification.md](specification.md) 的 `C-x` 决定;**现役** = 沿用 legacy 行为基线;**假定** = 无依据的占位值,必须在对应 `Q` 关闭后重评;**安全默认** = 关闭态,需显式开启。
「依据」列含义:**契约** = 由 [specification.md](specification.md) 的 `C-x` 决定;**现役** = 沿用 legacy 行为基线;**实现** = 当前代码采用的机制,取值并非需求契约;**假定** = 无依据的占位值,必须在对应 `Q` 关闭后重评;**安全默认** = 关闭态,需显式开启。
### 1.1 管道节奏与重试(`msgx.pipeline.*`
@@ -61,9 +61,9 @@
| `mailbox.shared-mysql.url` | 环境变量 | 安全 | 零入库,见 `.env.example`;同组 `username` / `password` |
| `datasources.default.connection-timeout` | `5000` | 假定 | 自有 PG 池(毫秒数,非 Duration 字面量);同组 `validation-timeout=3000``idle-timeout=300000``max-lifetime=1800000` |
| `datasources.default.data-source-properties.connectTimeout` | `3` | 假定 | 驱动级连接超时(秒);同组 `socketTimeout=30` |
| `kafka.producers.default.acks` | `all` | 契约`D2` | 允许环境变量覆盖 |
| `kafka.producers.default.enable-idempotence` | `true` | 契约`D2` | 允许环境变量覆盖 |
| `kafka.producers.default.max-in-flight-requests-per-connection` | `1` | 契约`D2` | 启动自检钉住三项联合满足 `D2`;允许环境变量覆盖 |
| `kafka.producers.default.acks` | `all` | 实现`D2` | 允许环境变量覆盖 |
| `kafka.producers.default.enable-idempotence` | `true` | 实现`D2` | 允许环境变量覆盖 |
| `kafka.producers.default.max-in-flight-requests-per-connection` | `1` | 实现`D2` | 启动自检校验当前三项配置;允许环境变量覆盖 |
环境变量清单以 `.env.example` 为准。
@@ -100,7 +100,7 @@
| 回填与投递 | `processing/BackfillService.kt``delivery/Dispatcher.kt``infra/kafka/KafkaDeliveryPort.kt` |
| 维护作业 | `jobs/JobRunner.kt``jobs/HistorySweepJob.kt``jobs/EventCleanupJob.kt``infra/persistence/SnapshotLogPurge.kt` |
| 持久化与恢复 | `infra/persistence/`(含 `jdbc/JdbcPgRepositories.kt``jdbc/JdbcCminmsgInboxRepository.kt`)、`infra/retry/``ProcFailure` / `ReplayService` / `FailureScheduler` |
| 启停与配置 | `PipelineLifecycle.kt``config/PipelineProps.kt``config/HistoryProps.kt``config/OperationDayProps.kt`(含运营日时区启动自检)、`config/MailboxProps.kt``config/KafkaD3Check.kt``D2` 三联合启动自检) |
| 启停与配置 | `PipelineLifecycle.kt``config/PipelineProps.kt``config/HistoryProps.kt``config/OperationDayProps.kt`(含运营日时区启动自检)、`config/MailboxProps.kt``config/KafkaD3Check.kt`当前 Kafka 生产配置自检) |
| 指标与健康 | `infra/metrics/PipelineMetrics.kt``infra/metrics/JobActivity.kt``infra/health/BacklogSnapshotProvider.kt``infra/health/JobRunnerHealthIndicator.kt` |
| 迁移 | `src/main/resources/db/migration/`(单基线 `V1__flight_state_baseline.sql``oracle11g/` 为占位) |
+8 -22
View File
@@ -4,28 +4,22 @@
## 1. 范围与非目标
**系统定位**:OMMS H5 查询系统的消息网关。收取 CIIMS adapter 信箱中 AODB 下发的 XML 报文:航班动态写入数据库并同步写 Redis,运营航班动态消息经 Kafka 发给运营航班显示界面;静态参考数据写入数据库,供 admin-api 只读。出站仅向 AODB 发参考数据类请求和日计划请求(经 `COUTMSGS`,消费方为 CIIMS adapter
**系统定位**:OMMS H5 查询系统的消息网关。收取 CIIMS adapter 信箱中 AODB 下发的 XML 报文,处理航班动态与静态参考数据;出站仅向 AODB 发参考数据类请求和日计划请求
**交付范围**`US-01``US-14``OPS-1``OPS-4`
**非目标**
- 航班当前态权威只在自有 PG;Redis 仅作查询投影,不作权威或处理状态。
- 航班当前态权威只在自有 PG,开发测试用 PostgreSQL;生产物理选型待 `Q14`,验证通过前不承诺 Oracle 兼容;Redis 仅作查询投影,不作权威或处理状态。
- 共享 MySQL 只做读写消息和写回处理标记,不改表结构、不建表;已回填的入站行超过保留期后由本系统清理(specification.md 的 `C-1`)。
- 本消息网关只有一个实例。
- 对外投递只承诺至少一次;同一航班(`FLID`)内保序,不同航班之间不承诺顺序。
- 测试环境用 PostgreSQL;生产环境尚未决定用 PostgreSQL 还是 Oracle 11g。
- 已结束的航班写入 Elasticsearch 历史库后从实时数据删除。
- 不生成航班/业务数据类报文,不提供 AODB 主数据编辑能力。
- 不调用 admin-api,不从 admin-api 拉取、补全或合并任何数据。
- 不在 Redis 缓存机位基础数据与登机桥映射,本版不交付(`C-10`)。
**查询侧(admin-api的数据面**admin-api 是只读数据层,不生产航班动态,也不保存实时航班;它的季度计划与基础数据都从本系统数据库读,其中季度计划供数方待定(specification.md 的 `Q25`)。基础数据的数据集为:
- 航班基础数据:外部状态码、航班类型、代理单位、延误异常定义。
- 配套基础数据:航司、航空集团、机场、机场集团、城市、国家、航站楼、航站楼区域、机位、机位类型、机位廊桥、登机口、行李滑槽、值机柜台、值机岛、行李转盘、机型、机号、机型分组。
其余能力不由本系统提供:航班动态 Excel 导出、字典;历史航班检索读 Elasticsearch 别名 `flight_hts`,索引名与字段映射待定(specification.md 的 `Q23`)。接口清单见 [legacy/flight-apis.md](legacy/flight-apis.md)。
**查询侧(admin-api**admin-api 从本系统数据库只读基础数据与季度计划供数方待 `Q25`);历史航班检索读 Elasticsearch`Q23`)。其余能力(航班动态导出、字典)不由本系统提供。
## 2. 用户故事
@@ -61,7 +55,7 @@
1. 一次只处理一条消息,取编号最小的未完成消息;处理中的消息不让后面的越过。
2. 报文不合法:进死信。报文合法但本系统不支持该类型:跳过留档,按已处理写回标记。原始报文留在信箱,已回填的行由本系统按保留期清理(`C-1`)。
3. 处理或提交失败:失败的事务回滚,消息保持未完成,下一轮自动重新处理。
4. 处理只动本系统数据库;发 Kafka回填信箱在处理完成之后单独做。
4. 发 Kafka回填信箱在处理完成之后做;下游失败不影响消息处理结果
5. 错误必须记录到对应消息的处理记录上,不能被外层吞掉。
### US-04 处理计划外航班(ADFT
@@ -80,9 +74,9 @@
**验收标准**
1. SIS 的 FLOP 部分列有 25 个动态消息子类型;现场需处理的 7 类为靠桥(`ABTM`)、延误(`DELY`)、计划机位(`PSDT`)、柜台(`CKDT`)、转盘(`CLDT`)、滑槽(`CHDT`)、登机门(`GTDT`。其中五类资源分配子类型已包含在上述 25 类中,但 SIS 注明 AODB 发来时 RMS 拒收;靠桥、延误在 SIS 的日计划字段中有定义,不属于上述 25 个 FLOP 子类型。现场报文按现有处理逻辑延续
1. 处理 7 类 FLOP 动态消息:靠桥(`ABTM`)、延误(`DELY`)、计划机位(`PSDT`)、柜台(`CKDT`)、转盘(`CLDT`)、滑槽(`CHDT`)、登机门(`GTDT`;未知子类型按不支持类型跳过留档(`US-03` AC2)。白名单其余子类型待 `Q3` 以真实报文确认后增补
2. 每个子类型有明确的处理规则:更新哪些字段;报文里字段为空表示清除还是撤销;航班不存在时怎么办。
3. 柜台、转盘、滑槽、登机门、机位五类资源分配报文,现场 AODB 实际会发,照常接收处理(消息接口规范写的是相反方向,与 AODB 核对确认);航线路线最多保留 4 条;未落到航班当前态的字段按信箱编号、路径和出现序号唯一记入自有数据库长期记录,保存原值,不随处理记录到期清理。
3. 五类资源分配报文(`CKDT``CLDT``CHDT``GTDT``PSDT`)正常接收处理;航线路线最多保留 4 条;未落到航班当前态的字段按信箱编号、路径和出现序号唯一记入自有数据库长期记录,保存原值,不随处理记录到期清理。
4. 数据写入 Redis 成功,这条消息才算处理完成;写失败不标记已处理,下轮重新处理。
### US-06 删除航班(FDEL
@@ -127,7 +121,7 @@
**验收标准**
1. `RQRD``RQFD` 各自同时最多一条已落信、未结案的请求;同一子类型发新请求时旧请求作废,新请求登记为待发送,等同一报文类型的在途请求收到应答、失败或超时后再落信。请求超过时限未等到应答,标记超时。
1. `RQRD``RQFD` 各自同时最多一条已落信、未结案的请求;同一子类型发新请求时旧请求作废,新请求待在途请求结案后再落信。请求超过时限未等到应答,标记超时。
2. 应答到达时按报文类型对应到等待中的请求;AODB 发错或迟到的应答不更新数据,记录后跳过。
3. 收到 EROR(AODB 错误回报):定位到本系统发出的请求,标记失败并告警。
@@ -142,7 +136,7 @@
### US-11 处理记录清理
**目标**处理记录只用于追踪消息处理情况和排查问题,没有长期保留价值
**目标**已了结的处理记录到期后可删除
**验收标准**
@@ -194,11 +188,3 @@
| `OPS-2` | 可观测:消息积压、处理失败、发送失败、标记写回失败都有监控指标和告警。 | 故障注入触发告警;检查监控面板。 |
| `OPS-3` | 测试隔离:测试环境的实例使用独立的数据库、Redis、Kafka 主题,不连接生产信箱。 | 配置检查。 |
| `OPS-4` | 切换与回退:停旧系统、启新系统完成切换;出问题回退时停新、启旧,未处理的消息由旧系统继续,数据不丢。 | 切换与回退演练记录。 |
## 4. HTTP 接口清单
| 接口 | 用途 |
|---|---|
| `POST /cminmsgs/send` | 联调工具写入报文(US-02)。 |
| `POST /schd/sync` | 发起日计划请求(US-09)。 |
| `GET /all/flights` | 查询全部动态航班(US-12)。 |
+2 -2
View File
@@ -175,8 +175,8 @@
| 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` 唯一 |
| INV-5 | 架构「数据归属与一致性」 | 航班当前态的权威写入只在自有 PG |
| INV-6 | implementation.md「权威模型」 | `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 | 投影写失败时,没有终态与回填意图落库;处理完成前事件不可投递 |