Files
airport-wiki/concepts/aodb/开源机场运营数据库(AODB)高层设计文档.md
2026-04-15 14:48:14 +08:00

511 lines
19 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 开源机场运营数据库(AODB)高层设计文档
## 1. 文档目标
本文档定义 AODB MVP 的技术方案基线,重点回答以下问题:
1. AODB 在 MVP 内承载哪些业务闭环,以及哪些能力明确不做。
2. 系统如何划分聚合、服务、数据流和事件边界。
3. 航班、里程碑、资源、告警等核心对象如何建模。
4. 发布事实如何在观测、裁决、审计和订阅之间保持一致。
5. 查询、订阅、部署、容灾和可观测性如何落到可实现架构。
适用范围:年旅客吞吐量 500 万至 3000 万机场,优先支持单机场部署。
## 2. 设计原则
- 单一事实源:AODB 对外发布单一当前权威事实,不暴露“谁最后写入”式伪一致。
- 事实分层:原始观测、裁决记录、发布事实必须分层建模。
- 写主清晰:每个核心聚合只允许一个服务写入,避免跨服务共享可变状态。
- 事件驱动:状态变化通过事件传播,系统通过契约解耦。
- 规则可解释:字段权威、冲突裁决、人工覆盖必须可追溯、可回放、可解释。
- 渐进复杂度:MVP 先建立稳定闭环,不引入复杂优化平台和长事务编排平台。
## 3. 范围定义
### 3.1 MVP 范围
首期只覆盖以下闭环:
- 航班计划导入与实时状态更新
- 航班配对与过站上下文最小建模
- 基础资源分配:Stand、Gate、Belt、Counter
- 关键里程碑跟踪与发布事实治理
- 延误、资源冲突和数据质量告警
- 对外查询接口与事件订阅
- 审计、人工裁决、重放与复核闭环
### 3.2 非 MVP 范围
首期不纳入以下能力:
- 全局优化排班和复杂资源优化求解
- 深度 AI 预测和自适应调度
- Flink 驱动的复杂 CEP 平台
- Temporal 驱动的复杂长事务工作流平台
- 多机场统一调度中心能力
## 4. 总体架构
### 4.1 架构分层
| 层级 | 主要能力 | MVP 主路径组件 | 说明 |
| --- | --- | --- | --- |
| 接入层 | 外部系统接入、协议解析、统一北向入口 | Kong Gateway、Apache Camel、SSIM 导入器 | 接收计划、动态、资源和人工操作输入 |
| 业务层 | 航班当前态、观测治理、资源分配、告警处置、外部接口 | Flight Operation Service、Milestone Service、Resource Service、Alert Service、External API Service | 承担领域逻辑和对外契约 |
| 事件层 | 事件骨干、重放、订阅分发 | Kafka、Outbox/CDC 发布器 | 负责异步传播和回放 |
| 数据层 | 事务存储、时序存储、缓存 | PostgreSQL、TimescaleDB、Redis | 保存当前态、审计链路和热点读模型 |
| 平台层 | 认证鉴权、部署、观测 | Keycloak、Kubernetes、Prometheus/Grafana/Loki | 提供运行时底座 |
### 4.2 核心技术链路
MVP 主链路采用“接入标准化 -> 观测入库 -> 裁决生成 -> 发布事实更新 -> 事件发布 -> 查询/订阅消费”的结构:
1. 外部计划或运行动态通过接入层进入系统。
2. Milestone Service 将输入标准化为 Observation,并按幂等键写入。
3. 规则引擎根据字段权威矩阵和当前上下文生成 Decision。
4. Flight Operation Service 更新 Published Fact 和当前状态摘要。
5. 同一事务内写入 Outbox,由 CDC 发布到 Kafka。
6. External API Service 对外提供查询接口和事件订阅接口。
7. 告警、人工裁决和重放都沿同一事实链路工作,不直接绕过 Published Fact。
### 4.3 领域划分与聚合边界
为避免多服务共同修改同一业务对象,MVP 采用以下聚合边界:
| 聚合 | 职责 | 主键 | 写主 | 发布事件 | 只读依赖 |
| --- | --- | --- | --- | --- | --- |
| FlightOperation | 航班当前权威态、运行状态、发布事实 | `flight_id` | Flight Operation Service | `FlightUpdated``PublishedFactUpdated` | Turnaround、MilestoneObservation、ResourceAllocation |
| MilestoneObservation | 里程碑原始观测、标准化观测、候选事实 | `observation_id` | Milestone Service | `MilestoneObserved``MilestoneNormalized` | FlightOperation |
| Turnaround | 到达航班、离港航班、飞机周转上下文 | `turnaround_id` | Flight Operation Service | `TurnaroundLinked``TurnaroundCorrected` | FlightOperation |
| ResourceAllocation | 资源占用、锁定、冲突、覆盖 | `allocation_id` | Resource Service | `ResourceAssigned``ResourceUnassigned``ResourceConflictDetected` | FlightOperation、Turnaround |
| AlertCase | 告警和处置对象 | `alert_id` | Alert Service | `AlertRaised``AlertAcknowledged``AlertCleared` | FlightOperation、ResourceAllocation |
边界约束:
- Flight 当前权威态只能由 `Flight Operation Service` 写入。
- Milestone Service 负责观测和候选事实,不直接改写 Flight 当前态。
- Resource Service 只拥有资源占用与冲突事实,不直接修改 Flight 当前态中的非资源字段。
- Alert Service 不产生业务事实,只管理处置状态和告警生命周期。
### 4.4 核心服务职责
- `Flight Operation Service`
- 管理 FlightOperation 当前态。
- 维护 Published Fact。
- 负责 Turnaround 建模和关联修正。
- `Milestone Service`
- 接收外部运行动态。
- 解析、标准化并形成 MilestoneObservation。
- 依据字段权威矩阵给出候选事实。
- `Resource Service`
- 管理资源主数据和资源分配。
- 进行适配校验、冲突检测、人工覆盖和回滚。
- `Alert Service`
- 管理告警、确认、关闭、抑制和处置轨迹。
- `External API Service`
- 提供查询接口。
- 提供事件订阅接口或订阅分发适配层。
- 不作为权威事实生成者。
## 5. 核心模型
### 5.1 核心标识约定
- Flight
- `flight_key``carrier + flight_number + op_date + leg_no`
- `flight_id`:内部不可变主键
- Turnaround
- `turnaround_id`
- 可关联一个到达航班和一个离港航班
- MilestoneObservation
- `observation_id`
- 幂等键优先使用上游报文 ID、序列号或批次 + 行号
- Resource
- `resource_id`
- `resource_type + resource_code` 唯一
- ResourceAllocation
- `allocation_id`
- 幂等键由 `resource_id + validity_window + assignment_source + correlation_id` 组合约束
### 5.2 核心实体与关系
- FlightOperation:指定运行日上的航班运行对象,包含当前发布事实和状态摘要。
- Turnaround:将到达航班、离港航班和飞机周转上下文关联起来,用于资源和时序联动。
- MilestoneObservation:里程碑观测记录,保留原始来源、标准化结果和候选事实。
- Resource:资源主数据,MVP 覆盖 Stand、Gate、Belt、Counter。
- ResourceAllocation:资源分配记录,含有效窗口、锁定类型、来源和覆盖原因。
- AlertCase:告警对象,关联 FlightOperation 或 ResourceAllocation。
- DataQualityFlag:对冲突、低可信度、超窗乱序、待裁决等问题做结构化标记。
关系约束:
- 一个 FlightOperation 对应多个 MilestoneObservation。
- 一个 Turnaround 可关联一个到达航班和一个离港航班,也允许只有单侧航班待补全。
- 一个 Resource 在时间轴上可关联多个 ResourceAllocation,但硬冲突不允许同时生效。
- AlertCase 可关联具体 FlightOperation、Turnaround 或 ResourceAllocation。
### 5.3 FlightOperation 最小字段组
- 主键:`flight_id``flight_key`
- 属性:`carrier``flight_number``op_date``leg_no``direction`
- 机体上下文:`aircraft_type``tail_number`(可空)
- 状态:`flight_status`
- 发布事实:计划 / 预计 / 实际时间类字段
- 当前资源摘要:Stand / Gate / Belt / Counter
- 质量摘要:冲突标记、待裁决标记、最近裁决摘要
- 关联:`turnaround_id`(可空)
### 5.4 Turnaround 最小字段组
- `turnaround_id`
- `arrival_flight_id`
- `departure_flight_id`
- `tail_number`
- `aircraft_type`
- `turnaround_status`
- `link_source`
- `link_confidence`
约束:
- 配对可以晚于航班导入发生。
- 配对修正必须产生 `TurnaroundCorrected` 事件并保留审计。
- 若未知配对,FlightOperation 仍可独立运行,但资源和里程碑解释能力下降。
## 6. 事实分层模型
### 6.1 三层模型
| 层 | 含义 | 是否可变 | 用途 |
| --- | --- | --- | --- |
| Observation | 上游原始或标准化观测 | 否 | 追溯、回放、取证 |
| Decision | 规则或人工裁决结果 | 否 | 解释为什么当前事实成立 |
| Published Fact | 当前对外权威事实 | 是 | 查询、订阅、共享 |
### 6.2 SSOT 定义
AODB 的 SSOT 不等于“数据库中的最后一次写入”,而是:
- 由 Observation 输入
- 经字段级权威矩阵与裁决逻辑处理
- 最终形成并发布的 Published Fact
### 6.3 状态写入三元信息
所有关键状态写入都必须附带:
- `source`
- `confidence`
- `decision`(可空)
其中:
- Observation 必须保存原始来源和原始时序。
- Decision 必须保存裁决者、依据、原因和裁决时间。
- Published Fact 必须能追溯到 Observation 和 Decision。
### 6.4 字段级权威矩阵(最小集)
| 字段 | 主来源 | 次来源 | 更正规则 | 人工覆盖 | 对外可见性 |
| --- | --- | --- | --- | --- | --- |
| ALDT | ANSP / 机场运行 | 航司 | 明确更正或高版本号优先 | 允许 | 返回当前值 + 来源 |
| AIBT | 地服 / 机场运行 | 航司 | 同上 | 允许 | 返回当前值 + 来源 |
| EIBT | 系统计算 | 运行动态派生 | 新计算覆盖旧计算并留历史 | 允许 | 返回当前值 + 可信度 |
| TOBT | 航司 / 地服 | 机场运行 | 最新有效更正优先 | 允许 | 返回当前值 + 裁决摘要 |
| TSAT | AODB / P1 PDS | 机场运行 | 新计算版本优先 | 允许 | 返回当前值 + 算法版本 |
| Stand Assignment | 机场运行系统 | 人工调度 | 人工覆盖优先并保留原因 | 必须审计 | 返回当前值 + 覆盖摘要 |
| Gate Assignment | 机场运行系统 | 人工调度 | 同上 | 必须审计 | 返回当前值 + 覆盖摘要 |
| Belt Assignment | 机场运行系统 | 人工调度 | 同上 | 必须审计 | 返回当前值 + 覆盖摘要 |
| Counter Assignment | 机场运行系统 | 人工调度 | 同上 | 必须审计 | 返回当前值 + 覆盖摘要 |
## 7. Flight 状态模型
### 7.1 最小状态机
- Planned:已导入计划但尚无有效运行动态。
- Active:已有运行动态、里程碑或资源变更。
- Completed:已达到收敛里程碑并进入归档策略。
- Cancelled:取消或无效,但保留完整历史。
### 7.2 状态迁移原则
- 状态迁移由 Published Fact 驱动,而不是由单个外部系统直接声明。
- 若存在冲突或裁决,不回滚 Observation 历史,只更新 Published Fact 和当前状态摘要。
- 状态修正必须能通过事件和审计链路回放。
## 8. 历史、审计与回放
### 8.1 数据存储视图
- `ObservationLog`
- 保存原始或标准化观测
- `DecisionLog`
- 保存规则命中和人工裁决
- `PublishedCurrentState`
- 保存当前对外权威事实
- `AuditTrail`
- 保存 `who / what / when / why`
### 8.2 基本约束
- PublishedCurrentState 的任何关键字段变更都必须能在 ObservationLog 和 DecisionLog 中找到原因链路。
- 人工覆盖不得改写原始 Observation,只能新增 Decision 并更新 Published Fact。
- 历史回放以事件和日志为准,不以任意时点快照为首期前提。
## 9. 资源模型与冲突治理
### 9.1 Resource 模型
每个 Resource 至少具备:
- `resource_id`
- `resource_type`
- `resource_code`
- `status`
- `capability_profile`
- `compatibility_constraints`
- `parent_resource_id`(可空)
- `operational_calendar`
### 9.2 ResourceAllocation 模型
每个 ResourceAllocation 至少具备:
- `allocation_id`
- `resource_id`
- `flight_id`
- `turnaround_id`(可空)
- `allocation_status`
- `assignment_source`
- `lock_type``soft` / `hard`
- `validity_window`
- `override_reason`(可空)
- `derived_from_event`
- `conflict_flags`
### 9.3 冲突分类
| 冲突类型 | 说明 | 是否阻断 | 是否允许人工覆盖 |
| --- | --- | --- | --- |
| 时间冲突 | 占用时间窗重叠 | 是 | 是 |
| 适配冲突 | 机型、能力或运行属性不匹配 | 是 | 受限 |
| 状态冲突 | 资源停用、维护、冻结 | 是 | 否 |
| 策略冲突 | 本地策略或运营规则违反 | 视规则 | 是 |
### 9.4 四类资源规则口径
- Stand
- 关注机型适配、拖曳、到离港时间窗、过站联动。
- Gate
- 关注旅客流程时间窗、国际国内属性、步行距离和能力约束。
- Belt
- 关注到港时序、机型、行李量经验参数和恢复能力。
- Counter
- 关注值机开放窗口、航司差异化规则和共享柜台能力。
### 9.5 人工覆盖原则
- 自动分配只产生建议或默认分配。
- 人工覆盖必须记录原因、证据、操作者和影响范围。
- 回滚必须和覆盖一样事件化和审计化。
## 10. 事件模型与一致性
### 10.1 事件分类
| 事件类别 | 说明 | 示例 |
| --- | --- | --- |
| Domain Events | 聚合内部事实变化 | `FlightUpdated``ResourceAssigned` |
| Integration Events | 对外共享的标准化事件 | `PublishedFactUpdated``AlertRaised` |
| Audit Events | 审计和裁决事件 | `ManualDecisionRecorded` |
| Case Events | 人工复核和告警处置状态变化 | `ReviewTaskOpened``AlertAcknowledged` |
### 10.2 MVP 事件清单
- `FlightImported`
- `FlightUpdated`
- `TurnaroundLinked`
- `TurnaroundCorrected`
- `MilestoneObserved`
- `MilestoneNormalized`
- `PublishedFactUpdated`
- `ResourceAssigned`
- `ResourceUnassigned`
- `ResourceConflictDetected`
- `AlertRaised`
- `AlertAcknowledged`
- `AlertCleared`
- `DataQualityFlagged`
- `ManualDecisionRecorded`
- `ReviewTaskOpened`
- `ReviewTaskClosed`
### 10.3 事件归属表
| 事件 | 归属聚合 | 触发条件 | 是否对外发布 | 是否可回放 |
| --- | --- | --- | --- | --- |
| `MilestoneObserved` | MilestoneObservation | 收到有效运行动态 | 否 | 是 |
| `PublishedFactUpdated` | FlightOperation | 当前权威事实发生变化 | 是 | 是 |
| `ResourceAssigned` | ResourceAllocation | 资源分配生效 | 是 | 是 |
| `ResourceConflictDetected` | ResourceAllocation | 检测到冲突 | 是 | 是 |
| `ManualDecisionRecorded` | Decision / Audit | 人工裁决完成 | 是 | 是 |
| `AlertRaised` | AlertCase | 达到告警条件 | 是 | 是 |
### 10.4 统一事件信封
所有业务事件必须具备:
- `event_id`
- `event_type`
- `schema_version`
- `occurred_at`
- `produced_at`
- `source`
- `idempotency_key`
- `correlation_id`
- `aggregate_id`
- `payload`
### 10.5 幂等、顺序和更正语义
- 所有写入事件必须携带 `idempotency_key`
- 顺序保证以 `flight_id` 为最小粒度。
- 更正必须显式表达,不允许静默覆盖已发布事实。
- 乱序允许在可配置窗口内重排,超窗进入审计旁路并打数据质量标记。
### 10.6 写库与发事件一致性
MVP 采用 `Outbox Pattern + CDC`
- 业务服务在同一事务内更新 PublishedCurrentState 并写入 Outbox。
- CDC / 发布器将 Outbox 可靠发布到 Kafka。
- 发布失败必须可重试、可恢复、可审计。
## 11. 查询接口与事件订阅
### 11.1 接口分离原则
- 查询接口负责读取 Published Fact、历史明细和告警状态。
- 事件订阅负责分发标准化事件流。
- 查询接口不是事实流;订阅接口不承担读模型查询职责。
### 11.2 查询接口
最小查询对象:
- FlightOperation 当前态
- MilestoneObservation 明细
- ResourceAllocation 生效集
- AlertCase 生命周期
最小要求:
- 支持按 `op_date``flight_id / flight_key`、资源类型、状态过滤
- 返回更新时间和数据版本
- 关键字段返回 `source / confidence / decision summary`
### 11.3 事件订阅接口
最小要求:
-`event_type``flight_id``op_date` 过滤
- 至少一次投递
- 支持断线重连和补偿
- 基于 `event_id` 或游标回放
- 支持租户隔离、连接数和推送速率限流
### 11.4 消费者契约
- 顺序仅保证到 `flight_id`
- 消费者必须按 `event_id` 去重
- 消费者必须处理数据质量标记和裁决摘要
- 回放窗口和游标语义必须文档化
## 12. 规则体系与人工复核
### 12.1 规则分类
- `authority rules`
- `validation rules`
- `conflict rules`
- `alert rules`
- `allocation heuristics`
### 12.2 规则最小模板
每条规则都必须定义:
- 输入
- 输出
- 优先级
- 命中条件
- 可解释字段
- 回放测试方式
### 12.3 人工复核对象
- 解析失败复核
- 里程碑冲突复核
- 资源冲突裁决
- 人工覆盖审批
### 12.4 Case 状态机
- `open`
- `assigned`
- `reviewing`
- `decided`
- `replayed`
- `closed`
原则:
- 所有人工动作都必须事件化。
- 所有人工动作都必须形成审计记录。
## 13. 非功能与部署
### 13.1 最小 SLO
| 指标 | 目标值 | 最低可接受值 |
| --- | --- | --- |
| 可用性 | 月度 99.95% | 月度 99.9% |
| 事件处理延迟 | P95 <= 2 秒 | P95 <= 5 秒 |
| 容灾恢复 | RTO <= 30 分钟,RPO <= 5 分钟 | RTO <= 2 小时,RPO <= 15 分钟 |
| 审计覆盖率 | 100% 关键变更可追溯 | 99.9% 可追溯 |
### 13.2 最小部署拓扑
| 组件 | 部署方式 | 高可用方式 | 失败影响 | 恢复方式 |
| --- | --- | --- | --- | --- |
| PostgreSQL / TimescaleDB | Stateful 部署 | 主备切换 + 定时备份 | 当前态和审计写入受影响 | 备份恢复 + 故障切换 |
| Kafka | 多副本集群 | 副本和 ISR 保障 | 事件流中断或降级 | Broker 恢复 + 消费追赶 |
| CDC / 发布器 | 无状态服务 | 多副本 + 幂等发布 | Outbox 堆积 | 断点续传 + 重试 |
| API / 业务服务 | 无状态部署 | 多副本 | 查询或写入能力降级 | 滚动恢复 |
| Redis | 主从或哨兵 | 缓存级高可用 | 热点查询性能下降 | 重建缓存 |
### 13.3 关键容灾约束
- PostgreSQL 必须具备 PITR 或等价恢复能力。
- Kafka 必须明确 `replication factor``min ISR`、保留窗口和重放策略。
- Outbox / CDC 必须具备断点恢复和重复投递幂等能力。
- 容灾演练必须覆盖数据库切换、事件堆积、订阅重连和回放。
### 13.4 可观测性要求
- 所有写路径必须具备请求追踪、事件追踪和审计追踪三类关联 ID。
- 关键链路必须暴露延迟、失败率、积压量和重试次数指标。
- 人工裁决、资源覆盖和更正事件必须进入统一审计检索视图。
- 订阅接口必须暴露连接数、滞后量、推送速率和补偿次数指标。
## 14. 文档边界与引用
- 本文档定义首期可开工的技术方案,不展开字段级数据字典和实现细节。
- 技术栈主选和启用条件以 `airport-wiki/concepts/aodb/开源技术栈选型决策.md` 为准。
- 需求边界以 `airport-wiki/concepts/aodb/AODB 核心需求提炼.md` 为准。
- 字段级权威矩阵以 `airport-wiki/concepts/aodb/AODB 字段级权威矩阵.md` 为准。
- 事件 envelope 和 payload 草案以 `airport-wiki/concepts/aodb/AODB 事件 Schema 草案.md` 为准。
- 最小部署拓扑和恢复策略草案以 `airport-wiki/concepts/aodb/AODB 最小部署拓扑草案.md` 为准。
- 关键设计取舍以 `airport-wiki/concepts/aodb/adr/` 下 ADR 为准。