20 KiB
Orbit · 星轨
Go + MySQL 构建的任务调度与流程编排平台。 业务应用通过 HTTP 提交任务,Worker 通过 WebSocket 执行,结果通过可靠订阅交付;任务状态、计划、流程检查点与审计保存在 MySQL。
- Pulse · 脉动:异步任务、延迟执行、定时计划、执行授权、重试与结果订阅。
- Weave · 织流:研发定义并发布流程,支持顺序、并行、条件分支、等待信号、有界查询和人工恢复。
- Console:账号密码登录的管理工作台,按应用与环境查看运行快照;支持任务/流程筛选、资源分页、ID 定位、审计与接入配置复制。控制台使用说明。
主分支:main。当前版本:v0.1.2。源码、SDK 和 Outbox 适配包采用固定版本发布,已发布标签不覆盖。变更见 CHANGELOG。
从这里开始
| 你要做什么 | 入口 |
|---|---|
| 第一次启动平台、设置管理员 | 快速开始 |
| 使用 Docker 启动,后续接入域名 | Docker 与域名部署 |
| 了解全部能力和用法 | 功能一览 |
| 业务 Go 项目接入 | SDK 怎么调用 |
| 直接运行完整场景 | examples:28 个可运行示例 |
| 嵌入现有 HTTP 服务 | HTTP + Outbox + Worker + Inbox |
| 查字段、错误码、权限及协议 | HTTP / WebSocket API、Go SDK 手册 |
| 配置、排障、备份、发布 | 配置与运维、运行手册 |
功能一览
每个示例目录都有 README、源码、启动方式和结果核对。接口手册包含字段、权限、错误码和恢复约定。
Pulse:任务与调度
| 功能 | 做什么 / 怎么用 | 可运行示例 / 接口 |
|---|---|---|
| 即时任务与提交幂等 | SubmitTask 提交固定处理器版本与 JSON;重报复用原操作键,GetTask 查当前状态 |
tasks · 任务接口 |
| 延迟任务 | DelayMS 从首次受理计时;AvailableAt 指定绝对时刻 |
delayed-task |
| 批量受理 | SubmitTasks 最多 32 项,逐项返回受理/拒绝/未知,按原身份补交 |
batch · 批量接口 |
| 自动 Worker | 注册处理器与版本,NewWorker(...).Run(ctx) 负责连接、授权、续租、上报与排空 |
worker · 运行器手册 |
| 安全重试 | 冻结次数、退避与总时限;明确可重试失败自动再执行,未知效果按安全策略核查 | retry · 重试策略 |
| 取消 | CancelTask 保存取消意图;运行中的处理器配合停止并结清 |
cancellation |
| 定时计划 | Cron / 固定间隔、时区、不可变版本、漏跑策略、暂停/恢复和触发历史 | schedules · 计划接口 |
| 资源退役 | 结清后退役订阅与队列,释放订阅名额,保留历史和审计 | 运行示例 · 接口与规则 |
| 队列资源控制 | 创建/配置队列并发、开始速率、积压上限和暂停;满额返回背压 | resources · 队列接口 |
| 应用共享配额 | 同一应用的多个命名空间/队列共享总额度 | application-resources |
| 资源键互斥 | ConcurrencyKey 协调跨队列同资源任务,资源端核验递增许可序号 |
keyed-concurrency |
| 优先级 | 任务优先级 0–9,结合等待时间排序与节点轮转派发 | priority |
| 查询与来源 | 按队列、状态、业务键、创建时间分页;追溯普通提交、计划、流程和人工重试来源 | task-query · 来源接口 |
| 历史与证据 | 查询每次尝试、原结果及迟到/冲突报告,保留原始记录 | history |
| 人工核查与重试 | ReviewTask 提交证据;RetryTask 创建关联新任务并保留审计 |
recovery |
Weave:流程编排
| 功能 | 做什么 / 怎么用 | 可运行示例 / 接口 |
|---|---|---|
| 定义与版本 | 研发使用 SDK 创建定义、发布不可变版本;运行实例固定启动版本 | workflow-definition · 定义格式 |
| 顺序、条件、并行与汇合 | 用有限结构组合任务与结果映射;持久化每一步和推进检查点 | workflow · 实例接口 |
| 时间与外部信号等待 | TIMER 到期继续;SIGNAL 按固定等待身份接收外部回执 | workflow · 信号设计 |
| 有界重复查询 | POLL 分别限制业务查询轮次和单轮请求重试,处理中继续等待,耗尽转核查 | workflow-poll |
| 暂停、继续、取消 | 停止推进后续工作,同时收集已发出的在途结果 | 控制接口 · 控制语义 |
| 人工恢复 | 按原因、证据、版本核查任务/步骤/等待;恢复沿用原历史、预算和截止 | workflow-recovery · 恢复接口 |
| 实例查询与审计 | 筛选分页,查步骤详情、历史激活、查询轮次、信号及状态时间线 | workflow-query · 历史接口 · 时间线 |
业务接入与管理
| 功能 | 做什么 / 怎么用 | 入口 |
|---|---|---|
| 可靠结果订阅 | 先创建订阅,再由 EventConsumer 通过 WebSocket 接收结果;业务提交后 ACK,失败按预算重新交付 | subscriptions · 消费 SDK |
| 事务 Outbox 公共包 | EnqueueTx 将待发请求写入业务事务,Run 后台发送;网络结果不明复用原身份 |
MySQL 适配包 · task-outbox |
| 业务结果 Inbox | 事件去重与业务更新同事务,提交成功后确认交付 | result-inbox |
| HTTP 服务完整生命周期 | 业务接口、Outbox、Worker、结果消费、就绪检查和有界关闭放进同一业务服务 | http-service |
| 平台身份与凭据 | 应用/命名空间/队列授权范围、凭据轮换/撤销;SDK 不直连平台数据库 | 鉴权 · 凭据管理 |
| 账号密码控制台 | 初始化管理员,按应用/环境/队列查看任务、计划、流程、交付与归档,列表和详情显示应用归属 | Console 手册 · 应用范围 |
| 保留策略与周期归档 | 配置各类数据保留天数,持久化归档计划/作业,分页、续跑、重试与文件核验 | 保留策略 · 周期归档 |
| 运维与观测 | 健康/readiness、独立指标端口、迁移核验、负载工具、备份恢复与故障演练 | 观测 · 运维 |
快速开始
需要 Go 1.27.1、MySQL 8.4,先创建专用数据库 orbit;下方管理员密码提示和读取队列 ID 的辅助命令使用 Python 3。程序通过环境变量配置,不会自动读取 .env。如当前 shell 设置了 GOTOOLCHAIN=local,必须安装满足版本要求的 Go。
1. 获取代码并迁移数据库
git clone --branch v0.1.2 https://git.yuntuo.hk/k2safe/orbit.git
cd orbit
export ORBIT_MYSQL_DSN='user:password@tcp(127.0.0.1:3306)/orbit'
export ORBIT_HTTP_ADDR='127.0.0.1:8080'
go run ./cmd/orbit-migrate up
DSN 替换为实际账号密码。--branch v0.1.2 检出固定发布版本;参与开发使用 git switch main。已有库先备份,再按升级与发布手册停旧写节点、迁移和核验;不修改已应用的迁移文件。
2. 一次性创建示例资源与管理员
下面在独立演示应用中授予所有流程及任务演示所需权限,并设置一个管理员。密码至少 12 字节,通过标准输入传递,不写入命令行或 Git。
umask 077
mkdir -p .local
python3 -c 'import getpass; print(getpass.getpass("设置管理员密码(至少12字节):"))' | \
go run ./cmd/orbit-admin bootstrap \
--application sample-app --namespace default --environment development \
--queue examples --worker-access --schedule-access --event-access \
--recovery-access --workflow-access --workflow-run-access \
--workflow-control-access --workflow-signal-access \
--workflow-recovery-access --workflow-audit-access \
--console-username admin --console-display-name 'Orbit 管理员' \
--console-password-stdin --output .local/development.credentials.json
管理员可在「应用接入」页面新建应用和初始队列、查看和调整有效期、平滑换证(默认长期 Token,换证时新旧共存 7 天),随时查看、复制包含当前 Token 的完整接入配置,或下载 orbit.env。设置 ORBIT_CONSOLE_APPLICATION_ADMIN=admin 指定唯一接入管理员,并通过 ORBIT_CREDENTIAL_KEY_FILE 配置 Token 加密保管密钥;本地 Compose 自动生成并持久保存。应用接入使用与接口文档。
初始化只运行一次,后续重启复用数据库、账号和 SDK 凭据。凭据 JSON 是服务端程序访问 API 的秘密文件,控制台不需要选择或上传它。已有资源增加管理员的方法见 Console 手册;真实接入按实际角色缩小权限。
3. 启动平台,进入控制台
export ORBIT_CONSOLE_QUEUE_ID="$(python3 -c 'import json; print(json.load(open(".local/development.credentials.json"))["queue_id"])')"
go run ./cmd/orbit
打开 http://127.0.0.1:8080/console/,用 admin 和刚设置的密码登录。页面自动使用当前访问地址请求服务端,统计与列表从平台接口读取 MySQL 中的数据。
4. 跑一条完整执行链
另开终端,从仓库根目录执行:
export ORBIT_URL=http://127.0.0.1:8080
export ORBIT_CREDENTIALS_FILE="$PWD/.local/development.credentials.json"
cd examples
go run ./health
go run ./worker
健康检查显示 liveness=alive readiness=ready;Worker 示例实际创建并执行三条文本任务,最后输出:
task=<任务ID> state=SUCCEEDED result={"text":"HELLO ORBIT"}
task=<任务ID> state=SUCCEEDED result={"text":"REUSABLE WORKER"}
task=<任务ID> state=SUCCEEDED result={"text":"DURABLE RESULT"}
worker_drained=true started=3 confirmed=3 running=0
刷新控制台可查看这些任务。继续在 examples 目录运行 go run ./schedules、go run ./workflow 或 go run ./workflow-poll 体验定时和流程;全部 27 个场景及特殊准备条件见 examples/README.md。
SDK 怎么调用
安装固定版本
在自己的业务项目中执行:
go get git.yuntuo.hk/k2safe/orbit/sdk/go@v0.1.2
# 业务事务需要 MySQL Outbox 时再安装:
go get git.yuntuo.hk/k2safe/orbit/adapters/outbox/mysql@v0.1.1
无需本地源码或 replace。SDK 是独立 Go module,只依赖标准库和 WebSocket 客户端;MySQL 驱动属于可选适配包。子模块的 Git 标签分别为 sdk/go/v0.1.2 和 adapters/outbox/mysql/v0.1.1。
提交、执行、接收结果
一次完整接入分为三个角色,可以分进程,也可以嵌入同一业务 HTTP 服务:
业务事务 → Outbox → HTTP 提交到 Orbit → WebSocket Worker 执行业务
↓
业务数据 ← Inbox ← WebSocket 结果订阅 ← 持久化结果
下面是业务函数中的提交片段;完整 imports、main、Worker 注册和收尾见 worker/main.go。baseURL 为实际平台地址,例如 https://orbit.example.com;token 和 queueID 从业务配置/Secret 注入。
client, err := orbit.NewClient(baseURL, orbit.Options{Token: token})
if err != nil { return err }
// operationKey 和完整 request 必须先保存在业务库;网络重报仍使用原值。
request := orbit.SubmitTaskRequest{
QueueID: queueID,
Handler: "object.prepare", HandlerVersion: "v1", PayloadVersion: "v1",
Payload: json.RawMessage(`{"object_ref":"objects/input"}`),
TaskTimeoutMS: 60000,
Retry: orbit.RetryPolicy{MaxAttempts: 1, AttemptTimeoutMS: 10000},
RecoverySafety: orbit.RecoveryReconcileOnly,
}
accepted, err := client.SubmitTask(ctx, operationKey, request)
if err != nil { return err }
current, err := client.GetTask(ctx, accepted.Task.ID)
if err != nil { return err }
fmt.Println(current.ID, current.State)
导入路径为 orbit "git.yuntuo.hk/k2safe/orbit/sdk/go"。处理器的名称、处理器版本和载荷版本必须与 Worker 注册能力一致;没有匹配的在线 Worker 时,提交成功也不会立即执行。
任务受理不等于执行成功。 同键重报返回原回执,最新状态用 GetTask 或结果事件核对。平台不能替外部系统保证“恰好执行一次”;副作用须使用业务幂等键、事务或证据核查。
结果通知使用 NewEventConsumer(...).Run(ctx)。先创建持久订阅,再提交希望接收的任务;消费函数在 Inbox 与业务变更明确提交后返回 nil,SDK 才 ACK。断线重连、重复交付和业务去重见消费手册。
现有 HTTP 服务如何接入
直接从 examples/http-service 开始,完整命令、配置及 curl 请求见运行手册。该工程提供:
init:在独立业务库创建 Outbox、业务表、Inbox 和结果视图。provision:创建可靠结果订阅,将订阅 ID 保存到部署配置。serve:启动业务 HTTP、Outbox 发送器、Worker 和结果消费者。- 业务请求返回本地受理状态;随后查询到平台 TaskID、执行结果和业务视图。
- 收到退出信号后,依次收尾 HTTP、发送器/Worker、结果消费者,最后关闭数据库。
只抽取发送器时使用公共 Outbox 包:EnqueueTx 加入调用方事务,不提交事务、不发网络请求;Run 在后台提交并核对平台回执。业务确认钩子与 Outbox 确认同事务执行。
Docker 与域名部署
本机给其他服务联调,可直接运行 ./scripts/orbit-local.py up,自动部署到 18080,生成管理员和 SDK 配置;完整地址、Docker 网络与启停方法见本地 Compose 测试环境。
仓库提供 Dockerfile、Compose 启动链和 Nginx 配置。按完整 Compose 手册注入数据库密码、构建镜像、启动 MySQL/迁移/核验、初始化管理员,最后启动 Orbit。手册也包括停止、更新与两节点覆盖配置。
- Console 同源访问:域名反向代理到 Orbit 后,页面自动使用这个域名,无需在界面填写服务地址。
- 业务 SDK:把自己的
baseURL/ 示例ORBIT_URL配置为该 HTTPS 域名,SDK 使用相应 WSS 地址。 - 网关保留 WebSocket Upgrade/Connection 头,健康检查使用
/health/ready。 - 停止容器保留 MySQL 和归档持久卷;更换镜像不等于删除数据。
配置与运维
配置完整示例见 .env.example。由 shell、部署平台或 Secret 管理器显式注入:
| 配置 | 用途 |
|---|---|
ORBIT_MYSQL_DSN |
平台数据库连接,迁移账号与运行账号按部署手册分开 |
ORBIT_HTTP_ADDR |
服务进程监听地址,例 127.0.0.1:8080 |
ORBIT_CONSOLE_QUEUE_ID |
控制台默认队列;不授予账号额外权限 |
ORBIT_CONSOLE_APPLICATION_ADMIN |
指定唯一可接入和管理各应用的控制台登录名;空值不开放跨应用权限,多节点保持一致 |
ORBIT_DB_MAX_OPEN / ORBIT_DB_MAX_IDLE |
数据库连接池上限 |
ORBIT_SHUTDOWN_TIMEOUT |
SIGTERM 关闭窗口,默认 10s |
ORBIT_WORKFLOW_TICK_INTERVAL / ORBIT_SCHEDULE_TICK_INTERVAL |
流程/计划后台扫描间隔,默认 1s |
ORBIT_RECOVERY_TICK_INTERVAL / ORBIT_RUNTIME_BATCH_LIMIT |
恢复扫描间隔与每批上限,默认 2s / 100 |
ORBIT_WORKER_CONNECTION_LIMIT / ORBIT_EVENT_CONNECTION_LIMIT |
每节点 WS 连接上限,默认各 128 |
ORBIT_DISPATCH_WORKERS / ORBIT_DISPATCH_CAPACITY |
派发并发和有界内存队列,默认 4 / 128 |
ORBIT_METRICS_ADDR |
独立内部指标监听,默认关闭 |
ORBIT_RETENTION_*_DAYS |
首次初始化保留窗口;控制台保存后以数据库策略为准 |
ORBIT_ARCHIVE_ROOT / ORBIT_ARCHIVE_STORAGE_ID |
周期归档卷路径与固定卷身份,二者一起配置 |
ORBIT_ARCHIVE_MAX_BYTES / ORBIT_ARCHIVE_TICK_INTERVAL |
归档卷预算和调度间隔,默认 10 GiB / 10s |
默认保留窗口:任务、流程、事件各 365 天,交付、Inbox、幂等记录各 90 天,审计 2555 天。控制台可修改策略并配置周期归档;未结清任务、未知效果、未确认交付等受保护记录不会按时间简单处理。当前归档导出并保留源数据,尚未提供源数据自动删除执行器。 详细规则见保留策略和归档作业。
常用检查:
curl --fail http://127.0.0.1:8080/health/ready
go run ./cmd/orbit-admin verify
go run ./cmd/orbit-admin observe snapshot
数据库禁止外键和级联删除;关联一致性由事务校验,保留唯一约束、索引和 CHECK。持久化模型及 SQL 字段都有中文注释。已有迁移不可回改,演进采用前向迁移。
项目目录
cmd/ 平台、数据库迁移和管理命令
platform/ 应用、身份、授权、幂等、事件、审计
pulse/ 任务、Worker、重试、队列、定时计划
weave/ 流程定义、实例、步骤、等待和恢复
model/ 公共持久化类型与校验
internal/ MySQL 存储、HTTP/WS、配置与观测
sdk/go/ 可独立引用的 Go SDK
adapters/outbox/mysql/ 可独立引用的 MySQL Outbox 包
examples/ 27 个可运行场景及各自 README
deploy/ Compose、Nginx 和部署配置
scripts/ 构建、回归、故障和发布核验
docs/ API、SDK、场景、设计及验收报告
测试、版本与边界
在仓库根目录执行:
make test vet build # 7 个模块的竞态测试、静态检查与构建
make sdk-check protocol-check docs-check
make integration # 临时 MySQL、真实平台、示例及故障回归
make console-check # 前端查询状态回归(开发机需 Node.js)
make console-e2e # 控制台端到端回归
集成测试需要 Docker、Python 3 和 OpenSSL 等工具,由脚本创建独立临时数据库并清理自建容器。生产容量与故障域验收另见交付清单;有限样本不能代表百万企业规模的生产容量。
v0.1.2 新增通用资源退役;此前已包含账号密码控制台、归档策略/周期作业、Outbox 公共包、HTTP 生命周期示例及统一示例目录;与上一版本的升级说明和验证结果见 CHANGELOG 与 本次验证。当前未提供源数据删除、其他数据库 Outbox 适配,也不把单机或隔离环境多节点测试等同于生产跨故障域高可用验收。