# 架构 本文写架构约束与归属;旧版报文的格式兼容以 [SIS 接口规范](legacy/SIS_AODB_RMS-V0.1.md) 和 [XSD](legacy/unisysaodbsis.xsd) 为依据。 ## 1. 系统定位与范围 msgexchange-v2 替换旧版 `msgexchange-api`,承接 OMMS H5 查询系统的消息网关职责。 ## 2. 总体架构 ```text CIIMS adapter(把 AODB 下发的 XML 写入信箱) │ 落信 ▼ 共享 MySQL:CMINMSGS(入站信箱) │ ▼ ──────── msgexchange-v2(单活动实例) ──────── ingress 收报 processing 处理(流程见「主流程」) delivery 投递 jobs 作业:回填 / 出站重试 / 历史清理 / 记录清理 ────────────────────────────────────────────── │ ├─▶ Kafka:msg / schd ── 运营航班显示界面 ├─▶ Redis:航班查询投影 ├─▶ 共享 MySQL:COUTMSGS ── 参考数据与日计划请求发 AODB ├─▶ Elasticsearch:航班历史 └─▶ 自有 PostgreSQL:航班当前态 / 管道与未映射字段记录 / 静态参考数据 ── admin-api 只读参考数据 ``` 跨阶段的待办与处理进度持久化在自有 PG,重启后从记录继续(`US-01` AC4、`US-03` AC3、`US-10` AC2)。 技术栈:Kotlin + JDK 25、Micronaut 编译期依赖注入、JDBC 持久化;数据库变更由 Flyway 管理,只作用于自有 PostgreSQL。依赖版本见 `build.gradle.kts`。 ## 3. 模块职责 | 模块 | 职责与边界 | |---|---| | `ingress` | 轮询信箱、登记入队、兼容入口落信(`US-01`、`US-02`);不解析业务报文。 | | `codec` | XML 解码,区分非法报文与可修复的解码失败(`US-03`)。 | | `processing` | FIFO 调度、业务身份绑定与去重、领域决策与落库(`SCHD`/`FLOP`/`FDEL`/`ADFT`/静态参考数据),航班类写 Redis 投影,未落到航班当前态的字段写 `UNMAPPED_FIELD`。 | | `delivery` | 读待发事件投 Kafka,聚合 `schd`,失败后重试(`US-08`;`C-9`)。 | | `jobs` | 回填、出站重试、航班历史与到期记录清理;不占主泵 FIFO(`US-10`、`US-11`、`US-14`)。 | | `domain` / `config` | 领域状态、事件和决策模型,以及运行参数。 | | `infra` | 仓储(JDBC/stub)、外部适配器(共享信箱、Kafka、Redis、航班历史存储、AODB 出站)、重试、健康检查与日志;对其他模块只暴露接口。 | ## 4. 主流程 航班动态消息走满全链,其余类别只换其中几步: 1. **收报**:按「处理时间为空」发现信箱行,登记入队(`INV-1`)。 2. **主泵**:按最小未完成 `MSG_ID` 取队头,解码,按业务身份去重(`US-03` AC1;implementation「消息、身份与决策」);非法或不支持的报文无副作用,终态留档(`US-03`)。 3. **事务一**:持 `PIPELINE_LOCK`,领域变更、未映射字段记录与待发事件一起提交。 4. **投影**:写 Redis,写成功才算处理完成(`INV-10`);失败保持未完成、下轮重写投影,业务效果幂等(`US-03` AC3)。 5. **事务二**:处理终态与回填意图一起提交。 6. **回填**:作业把处理标记写回共享信箱(`US-10`);写不上的记录在案并告警。 7. **投递**:读待发事件发 `KAFKA:msg` / `KAFKA:schd`,至少一次(`C-9`);一直失败的记录保留可查并告警(`US-08`)。 其余类别与这条主干的差异: | 类别 | 与主干的差异 | 完成判据 | 失败时 | |---|---|---|---| | 日计划(`DNLD`/`RESP`) | 第 3 步改为每批一个事务,第 5 步在整包完成后 | 整包成功,含 Redis 刷新(`US-07` AC4/AC5) | 不标记已处理,下轮整包重处理(`US-07` AC4) | | 静态参考数据 | 无第 4 步;一个事务完成落库、终态与回填意图 | 该类落库成功(`US-13` AC1) | 校验不过整类不动,其他类照常(`US-13` AC2) | | 出站请求 | 不走收报队列:登记新请求并作废同子类型旧请求;`RQRD` 与 `RQFD` 各自最多一条在途,后续请求待前一条结案再写入 `COUTMSGS` | 请求已写入信箱(`US-09` AC1) | `jobs` 按 `REQ_TRACK` 重试仍有效且确认未落信的请求;写入结果不明时记录并告警,不直接重发;交付承诺只到落信(`C-4`) | | 航班历史清理(作业) | 不走消息队列:历史写入成功后物理删除 | 实时数据已删(`US-14` AC3) | 历史写不成功不删,下轮重来(`US-14` AC3) | ## 5. 数据归属与一致性 | 存储 | 承载内容 | 职责说明 | |---|---|---| | 自有 PostgreSQL | 消息处理状态、回填意图、待发事件、出站请求状态、航班当前态、未映射字段与静态参考数据 | 航班当前态的唯一权威;本地事务只覆盖此库(`INV-5`)。 | | Redis | 航班查询投影 | 由本系统根据 PG 当前态维护;不存处理状态(`INV-11`)。 | | 共享 MySQL | 入站与出站信箱 | 外部邮箱边界;不改表结构,出站交付止于落信(`C-2`、`C-4`)。 | | Elasticsearch | 已结束航班的历史 | 历史写入成功后才删除实时航班(`D1`)。 | 跨存储步骤不能并入 PG 事务,由持久意图与幂等重试衔接;具体分段见「主流程」。 ## 6. 关键决策 以下决策补充主流程的跨存储边界。 | 编号 | 决策及理由 | 证据 / 偏差 | |---|---|---| | D1 | FDEL 的航班状态变更与待发删除事件同一事务提交;历史清理先确认历史写入成功,必要时登记待发删除事件,再物理删除。 | `US-06` AC1、`US-14` AC3 | | D2 | `msg` 单分区投递;同一 `FLID` 按事件顺序发送,队头失败时暂停该航班的后续事件。生产端须保持发送顺序,重发可能重复。 | `US-08` AC2、`CLM-3`、`C-9` |