Files
orbit/docs/02-technical-design.md

144 lines
12 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.
# Orbit 技术方案
> 版本 0.2 · 2026-09-17。Orbit 统一项目内保留 Pulse 与 Weave 两个模块。本文描述总体技术方案;基础、任务执行和流程执行链路已实施,生产拓扑与容量验收仍按持续计划推进。
## 1. 技术基线
| 项目 | 决策或建议 |
| --- | --- |
| 项目形态 | Orbit 通用平台,Pulse 负责任务与时间调度,Weave 负责流程编排 |
| 语言 | 当前基础使用 Go 1.27.1 |
| 接入 | HTTP + WebSocket,JSON;生产使用 HTTPS / WSS |
| 存储 | MySQL 8.4+,保存两个模块的权威状态;生产高可用拓扑待实际部署验收 |
| 服务端结构 | 核心应用逻辑独立于 HTTP / WS 适配层;建议显式依赖装配 |
| 数据访问 | 当前采用显式 SQL、普通 Go 模型、短事务;未引入 ORM |
| SDK | 首版 Go SDK,统一连接配置与鉴权,分别暴露任务与流程能力 |
| 必需外部组件 | MySQL;首版运行不依赖独立 Redis、消息队列或协调服务 |
| 运维输出 | 结构化日志、健康接口、指标与追踪接口;可接入既有监控系统 |
基础实现已选择 MySQL 8.4+,本轮在 8.4.10 测试。HTTP 与 WS 可复用成熟 Go 库;基础库被编译进程序不构成新增独立中间件服务。
## 2. 模块边界
| 模块 | 拥有的数据与行为 |
| --- | --- |
| 公共接入与治理 | 身份、环境、权限、协议、限额、公共审计与可观测接口 |
| Pulse | 任务、尝试、租约、队列额度、定时计划、执行结果和任务恢复 |
| Weave | 流程定义与版本、实例、步骤、分支、等待、信号、查询轮次、暂停与流程恢复 |
Weave 通过 Pulse 的应用层接口创建或取消任务。Pulse 的任务内核只保存通用关联信息,不理解行业业务或特定流程图。
两个模块可以共享一次事务,但不能任意直接修改对方的表。由应用服务显式传递事务上下文,在各自模块内完成约束校验。公共事务协调代码不应演变为包含所有业务规则的大对象。
执行一次任务的自动重试由 Pulse 管理;Weave 根据步骤最终结果决定下一步、等待处理或结束。Weave 不为同一执行失败再偷偷启动一套叠加重试循环。
当前 `pulse/model/` 与 `weave/model/` 已包含模型,服务入口、SDK 与迁移结构见 [数据模型基线](07-data-model.md)。执行引擎与业务接口按开发计划推进,模块边界通过接口与数据所有权保持。
## 3. 运行结构
```mermaid
flowchart LR
B[业务系统] -->|HTTPS 提交与管理| H[HTTP 接入]
W[业务 Worker / SDK] <-->|WSS 双向通信| G[WS 会话网关]
H --> P[Pulse 任务与调度]
H --> F[Weave 流程编排]
F -->|模块接口创建步骤任务| P
G --> P
P --> D[(MySQL 权威状态)]
F --> D
D --> R[恢复与内部事件处理]
R --> P
R --> F
```
首版建议同一个服务程序包含 HTTP、WS、调度、派发、恢复、流程推进及事件交付等角色,多实例运行。配置预留角色启停,后续可按负载拆运行进程;拆进程不要求先拆仓库或协议体系。
业务处理器留在 接入方业务项目的 Worker 中。平台内部定时唤醒等内置处理器仍需遵守任务状态、幂等和资源边界,不通过直接改业务状态绕过机制。
## 4. 数据与内存的分工
- MySQL 保存权威任务状态、授权租约、流程检查点、计划进度、幂等与待交付事件。
- 内存保存 WS 连接、候选任务引用、近期时间索引及可重建的统计。
- 内存唤醒只减少等待;遗漏唤醒必须能通过有界、索引化的数据库检查恢复。
- 领取、续租、完成及流程推进等决策访问权威写入节点;不能基于滞后的只读副本授予执行权。
- 关键状态落库后才确认成功。仅把日志写入数据库、把执行事实长期留在内存,不满足该设计。
MySQL 的事务与行锁提供并发更新基础,但任务状态机和幂等语义仍由平台实现。[MySQL 事务模型](https://dev.mysql.com/doc/refman/8.4/en/innodb-transaction-model.html)
## 5. 多实例派发与 WS 归属
每个 Worker 的连接由当前接入节点管理。该节点根据本地连接的授权队列、兼容版本与容量,按需领取任务并持久化分配,然后通过本地连接发送。
提交请求可能进入 A 节点,而可执行 Worker 连接在 B 节点。B 通过共享 MySQL 中的待执行记录发现任务;首版不要求另设消息总线来转发节点间通知。
领取采用有界批次、明确索引与短事务,可评估 `SKIP LOCKED` 或条件更新。发送 WS 消息、等待确认与执行业务均在事务之外。
数据库检查由平台按活跃队列/分区统一调度,不能为每一个空闲连接都启动高频数据库扫描。跨节点发现延迟进入调度延迟指标,不能宣称 WS 消除了数据库轮询。
节点失效后 Worker 重连其他节点,先依据 MySQL 核对会话与租约,再续接或停止旧尝试;不依赖负载均衡的粘性会话保证正确性。
## 6. 定时与流程推进
Pulse 扫描有索引的到期计划或任务,受控地产生可执行工作。近期时间索引可以缓存在内存,进程重启后按计划进度重建。
Weave 与 Pulse 同库时利用两个明确的事务边界:
1. **步骤任务创建事务**:更新流程/步骤状态,并通过 Pulse 接口创建下一步任务,一起提交。
2. **任务结果接续**:Pulse 保存终态时同时保存内部结果事件;Weave 可异步消费该事件,在一个新事务内更新步骤、推进流程、创建后续任务并标记事件已处理。
此处不需要跨服务 RPC 或外置 MQ。事件仍必须持久化并可去重,防止进程在任务完成后、流程推进前宕机造成停滞。
Weave 的信号、等待、有界查询、暂停、取消和人工恢复细节见 [流程设计](06-workflow-spec.md)。进入待核查状态也必须产生内部状态事件,不能只有任务终态才能让流程感知异常。
有界查询通过“查询任务 → 保存处理中结果 → 持久化等待 → 下一轮任务”推进。轮次与任务创建原子提交,单轮请求的自动重试仍归 Pulse;等待不占用业务 Worker。查询总时限、轮次数与单轮尝试组合都有限制。
暂停建议通过共享事务更新流程控制版本和 Pulse 的通用执行门控;业务任务领取、开始及后续尝试必须校验门控。控制门限与领取竞争采用一致的锁定/版本协议,单次读取后脱离事务决定开始不满足要求。Pulse 不需要读取流程图或理解业务含义。已授权执行、内部结果收集与到期记录继续进行,恢复所需推进记录必须持久化。
流程定义和分支计算不能在长数据库事务里等待外部调用。一次推进设工作量上限;大规模并行展开分批持久化,使用检查点恢复。
## 7. 并发、限流与扩展
- 根据队列或稳定路由键建立逻辑分区;队列数与租户数分开,不能默认一个租户创建一个平台队列或一条连接。
- 使用短事务协调跨节点的有效并发额度和同业务键执行许可,明确获取与释放顺序。
- 一条连接慢或一个应用积压时,通过有界缓冲、配额与公平调度控制影响。
- 心跳续租可按批发送,但逐项校验身份;批量减少通信或事务开销,不取消可靠持久化要求。
- 活跃状态和长期历史分开组织,归档、扫描及补跑都有资源预算。
- 先通过基准与故障测试验证容量,再决定物理分库。物理分片前需明确流程与步骤任务的同事务路由范围。
首版不承诺全局 FIFO、跨地域多活写入或无限队列容量。严格顺序应通过明确的业务序号与流程依赖表达,不能从 WS 单连接传输顺序推导出来。
## 8. SDK 与业务接入
建议 SDK 独立 Go module,避免把服务端 SQL、迁移和存储依赖带入业务项目。服务端实现和 SDK 使用同一份协议规范。
目标 SDK 能力包括:任务/流程客户端、Worker 运行组件、连接恢复、执行上下文、结果确认、追踪传播,以及可选的业务 Outbox 适配层。
已确认由研发通过 Go SDK 描述并发布流程。建议 SDK 生成版本化 JSON 定义,服务端校验并保存不可变版本;流程发布与实例启动是独立操作。定义构建 API 不上传业务闭包或要求 Orbit 执行业务 Go 源码,完整接口形式仍待评审。
业务处理器接收任务身份、参数、取消上下文及当前执行信息。接入文档必须解释副作用幂等、结果未知、续租失败与停止行为,不能让 SDK 的自动重试掩盖这些责任。
## 9. 生产部署与数据安全
建议至少部署两个平台实例用于应用层故障接管,放在适当的故障域。MySQL 必须采用明确的高可用与备份方案;其具体拓扑和数据确认语义单独验收。
MySQL 的 InnoDB Cluster 等成熟方案可以提供复制与故障切换,但配置、维护与恢复责任仍需要落实。[MySQL 高可用说明](https://dev.mysql.com/doc/refman/8.4/en/mysql-innodb-cluster-introduction.html)
数据库不可用时,停止新的受理确认、执行授权与流程状态推进;续租未确认的 Worker 按已确认租约边界处理。不能切换到只有内存确认的临时模式。
发布需排空连接、保留兼容的旧处理器版本、按步骤迁移数据库;禁止多实例启动时无协调地自动修改表结构。备份恢复需要核对已经发生的外部业务效果。
具体容量、消息大小、扫描周期、心跳、租约、连接上限与恢复时限由 [生产验收](05-production-acceptance.md) 给出测试证据后确定。
## 10. 工程规范建议
以下作为实施前的工程基线草案,与具体框架、路由库的选择分开讨论:
- **依赖方向**:协议适配层调用应用服务,应用服务协调领域规则与存储接口;核心状态机不依赖 HTTP / WS 对象。Pulse 不反向依赖 Weave 的流程规则,公共包不得包含接入方的专用业务逻辑。
- **并发与生命周期**:后台循环、连接读写、处理器均有明确的创建与退出归属;通过上下文传播取消与时限,限制 goroutine、缓冲及数据库连接数量。捕获处理器 panic 后按副作用安全等级处理,不能默认重跑。
- **错误契约**:区分协议错误、权限错误、状态冲突、临时基础设施错误、业务失败与结果未知。错误码保持兼容,日志保留内部原因,对外响应不泄露 SQL、密钥或敏感参数。
- **配置**:启动校验租约、续租、超时、容量与保留期限之间的约束;动态配置有版本、审计和明确生效范围。密钥独立管理,不放入仓库或普通配置快照。
- **数据库演进**:迁移脚本版本化,通过受控单一执行入口应用;滚动升级先做兼容性扩展,再迁移数据和收缩旧结构。数据修复使用可审计操作流程。
- **可观测性**:任务、尝试、流程、步骤与请求 ID 用于日志和追踪关联;租户 ID、任务 ID 等无界值不作为常规指标标签。审计事件与调试日志分别保留。
- **质量检查**:建立格式、静态检查、适用的 Go 竞态检测、协议兼容和迁移检查;使用真实 MySQL 验证事务、锁竞争与恢复,不能仅依靠存储 Mock 得出并发正确性结论。
- **发布与接入**:服务端、SDK 与处理器维护独立版本和兼容矩阵;变更给出升级顺序与迁移说明。业务接入验收覆盖幂等、未知结果、取消和恢复,不能仅以 SDK 调用成功作为完成标准。