状态:v2(已按 challenge 修订)。范围对齐既有定稿:单机优先、分布式为高层实现、AI agent 不实现(见
redesign-and-roadmap.md§3 与extension-points.md)。
| # | 决策点 | 结论 | 理由 |
|---|---|---|---|
| D1 | 实例间通信总线 | 内置中转(PlaneRelayBus)起步,NATS 作为后期选项 | 零外部依赖、保持单二进制部署体验;NATS 规模价值在小集群不兑现。EventBus trait 不变,后期可无痛替换 |
| D2 | agent 管理实例方式 | 进程级(spawn sohara serve --admin) |
隔离与崩溃安全最好,复用 release 二进制与全部单机能力;重启恢复语义显式化(见 §5) |
| D3 | Gateway 默认分发模式 | proxy 为主,bus 显式声明 | 默认同步请求-响应;mode: bus 的路径才走总线(异步语义,发布即返回) |
目标(对应需求 1–5):
非目标(明确排除):控制面多副本 HA/选举、自动扩缩容、分布式事务、agent 自治编排、AI agent。
┌────────────────────────────────────────────┐
外部请求 ──────────▶ │ sohara-plane(控制面,单实例进程) │
│ ┌──────────┐ ┌──────────┐ ┌───────────┐ │
│ │ Gateway │ │ Manager │ │ Scheduler │ │
│ │ 统一入口 │ │ API+全局UI│ │ 路由/生命周期│ │
│ └────┬─────┘ └────┬─────┘ └─────┬─────┘ │
│ └──────┬─────┴───────────────┘ │
│ Registry(期望状态唯一来源) │
└──────┬───────┴───────────┬─────────────────┘
控制通道(agent 拨出:心跳+指标上报、命令拉取;HTTP/JSON+token)
┌──────────────┴──────┐ ┌───────┴──────────────┐
│ sohara-agent (机器A)│ │ sohara-agent (机器B) │
│ 实例进程管理/健康检查│ │ 同左 │
│ ┌──────────────┐ │ │ ┌──────────────┐ │
│ │sohara serve │ │ │ │sohara serve │ │
│ │ --admin 9528 │ │ │ │ --admin 9528 │ │
│ └──────┬───────┘ │ │ └──────┬───────┘ │
└──────────┼──────────┘ └──────────┼───────────┘
│ 数据通道(D5a:plane 中转;D5b:NATS)│
└─────────────────────────────────────────┘
组件职责:
| 组件 | 职责 |
|---|---|
sohara-agent(每机一个守护进程) |
管理本机 sohara 实例进程;本地健康检查(1s 节拍);心跳/指标上报(5s);执行 plane 命令;转发总线消息 |
sohara-plane |
Registry(期望状态唯一来源)+ Manager API(部署/生命周期/监控查询)+ Scheduler(路由、健康策略)+ Gateway(统一入口)+ 总线中转(D5a) |
| 数据通道 | 实例间通信(§2.2):D5a 内置中转,D5b NATS(后期) |
| 单机 Dashboard | serve 模式内嵌 /admin/ui(§6) |
| 全局 Dashboard | Manager 提供的 Web UI(§7) |
ControlTransport trait,将来可替换 gRPC/QUIC。--admin-token(D1),agent 用同一 token 访问实例。token 缺失时管理端点 401。/admin/health(轻量),快故障秒级发现(plane 决策允许滞后,见 §5)。RunReport 字段、资源粗值、队列深度——D1 后才有)。{op, instance, seq});agent 拉取执行并回执;seq 重连去重。对账兜底(§3)保证命令丢失后状态仍收敛。sink.queue 发布 → 本机 agent 上报 plane → plane 按订阅表推给订阅实例所在 agent → agent 注入该机 InProcessBus → 既有 queue 触发器原样消费。NatsBus 实现同一 EventBus trait + nats 触发器;JetStream 提供持久化、至少一次、积压保留;配合单机幂等键消重;需要时提供 request-reply。nodes:
- { id: n1, addr: 10.0.0.11:9529, tags: [zone-a, gpu] }
flows:
- id: flow-orders
name: orders
yaml: ./flows/orders.yaml # plane 持有内容并分发
instances:
- id: orders-1
node: n1
flow: flow-orders
desired: running # running | paused | stopped
policy: { restart: always, max_restarts: 5, backoff: 2s, health_failures: 3 }
routing: { weight: 2, sticky_key: order_id }
bindings:
- { path: /webhook/orders, mode: proxy } # 缺省即 proxy(决策 D3)
- { path: /tasks/orders, mode: bus, topic: orders.events } # 显式异步
starting → running ⇄ paused → stopping → stopped;异常 → failed → restarting → starting(受 policy 约束);失联 → unknown。模式语义(决策 D3):
| 模式 | 语义 | 适用 |
|---|---|---|
proxy(默认,未声明 mode 即此) |
反向代理到所选实例的 http 触发器(agent 注册实例端口) | 同步请求-响应(webhook) |
bus(显式 mode: bus) |
发布到总线 topic,订阅实例竞争消费;发布即返回,无响应回执 | 异步任务/作业队列 |
选择策略:
round-robin:轮转(默认,D3 即有)。hash:对 sticky_key 一致性哈希;弱 sticky——实例增减时允许漂移,重试可落到别的实例;正确性靠业务幂等键(文档化,不承诺「同一键必须同一实例」)。tags:标签/权重亲和 + 过滤(延后,未实现)。least-loaded:按队列深度/CPU/错误率加权——依赖 D1 的队列深度指标,D5 之后启用。失败处理:unknown/failed/stopped 实例摘除;proxy 请求级重试(幂等安全);全挂 503 + 告警。
max_restarts 熔断为 failed + 告警)。plane 基于 5s 心跳收敛决策,允许秒级滞后(快故障由 agent 本地兜底)。serve --resume/等价支持)。restart: always 的实例必须声明 checkpoint store,否则策略降级为「只告警不重启」,避免静默重复投递。扩展现有 admin API(现在只有 health/metrics/pause/resume):
| 端点 | 内容 |
|---|---|
GET /admin/status |
flow 元信息、triggers 列表、步骤 + 实时 StepStat、paused、run_id、启动时间、approve 队列概要 |
GET /admin/history |
本实例运行历史(run 记录 + serve 停止时也写一条,D1 补齐) |
GET /admin/approvals |
approve 停放队列列表(步骤 + 数量 + 样例) |
GET /admin/errors |
近期错误环形缓冲(executor 打点处新增) |
--admin-token |
管理端点鉴权(D1;agent 与 plane 使用) |
GET /admin/ui:内嵌静态单页(vanilla JS/htmx,rust-embed 打进二进制,无前端构建),页面:
数据走上述 JSON API,UI 2–5s 轮询。--admin 未开启时 UI 不可用(保持默认零暴露)。
同单机 UI 技术栈,静态资源内嵌 plane 二进制。页面:
| 阶段 | 内容 | 验收 |
|---|---|---|
| D1 ✅ | 单机 Dashboard:admin API 扩展(status/history/approvals/errors/错误环形缓冲/--admin-token)+ 内嵌 /admin/ui;serve 停止写 history;CLI serve --resume |
已实现:sohara serve --admin 打开 UI;status/errors/approvals/history 端点可用;无 token 401;暂停期间事件不处理;停机写 history |
| D2 ✅ | sohara-agent:进程管理(spawn/kill/重启退避)、本地 1s 健康检查、心跳上报、命令执行、token;单机 serve --resume |
已实现:sohara-agent crate(实例监督状态机/重启策略/HttpTransport 心跳+命令队列+seq 去重);e2e 用真实 sohara 二进制验证拉起/健康/停机;plane stub 测试验证心跳与 pause 命令执行 |
| D3 ✅ | sohara-plane 基础:Registry(JSON 原子持久化)、Manager API(instances CRUD/desired 更新/flows)、/agent/heartbeat+/agent/ack 接收端(命令队列+seq 去重)、desired/actual 对账(心跳返回命令+期望实例集,agent 对账成员与状态) |
已实现:声明实例 → agent 拉起真实 sohara 进程;desired=stopped → 实例停机;desired=running → 重启;状态持久化跨重启 |
| D4 ✅ | Gateway + 调度:路由表(/api/routes,path→flow_id)、proxy 默认模式(bus 显式声明,暂返 501 待 D5a)、round_robin/hash 策略(tags/least-loaded 延后)、健康摘除(仅 running 且带 trigger 地址可路由)、请求级重试(2 候选)、全挂 503、Gateway 免 token(外部统一入口) |
已实现:两个真实实例按 round-robin 均分流量;停一个实例后流量全部切到存活实例 |
| D5a ✅ | PlaneRelayBus:实例 --relay <plane> 桥接(sink.queue 发布 → plane 邮箱;pull 循环注入本地 InProcessBus → queue 触发器原样消费)、plane /relay/publish|pull(每主题有界 1000 条,超限丢最旧,游标按订阅者独立)、Gateway mode: bus 发布即返回 202 |
已实现:实例 A(http→queue sink)跨机投递到实例 B(queue trigger→file,优雅停机 flush 落盘);Gateway bus → B 同样到达 |
| D5b | (可选,后期)NATS/JetStream:NatsBus + nats 触发器;least-loaded 策略启用 |
跨机持久化投递;重启不丢消息 |
| D6 ✅ | 全局 Dashboard(/ui:节点/实例矩阵、生命周期按钮、声明表单、路由管理、事件历史)+ 实例详情直查代理(/api/instances/:id/status 透传 admin token)+ 集群事件历史(声明/期望变更/状态迁移,200 条环)+ 安全收尾(plane token 覆盖 /api、/agent、/relay 与 /ui;实例 admin token 直查透传;Gateway 前置 LB 与 mTLS 评估:单点已接受,HA 延后——见 §9) |
已实现:UI 401/200(token)、状态代理、事件流、三向 token e2e |
keep-running(保持现状运行),命令队列重连补拉;期间 Gateway 不可用(单点,明确接受,HA 延后;D6 评估前置 LB)。/api/*、/agent/*、/relay/* 与 /ui;实例 admin token 由 plane 状态代理透传;relay token 独立。mTLS 与 Gateway 前置 LB 为可选增强(控制面单点已接受,HA 延后)。| 现有 | 用途 |
|---|---|
EventBus trait(core) |
D5a PlaneRelayBus、D5b NatsBus(同 trait,单机 InProcessBus 不动) |
Trigger trait + queue 触发器模式 |
D5b nats 触发器(复用有界通道/背压/优雅停机);D5a 复用既有 queue 触发器 |
| admin API(S6) | agent 健康检查/指标采集;D1 扩展为 Dashboard 数据源 |
RunReport/StepStat(S6) |
心跳指标快照 → Scheduler 决策 |
| run history 文件 | D1 补 serve 停止历史;agent 上报 → 全局聚合 |
PauseGate(S6) |
plane pause/resume 命令落点 |
release 二进制 sohara serve --admin |
agent 进程级管理(决策 D2);单机 CLI 仅增 --admin-token/--resume 两个 flag |
新增 crate:sohara-agent、sohara-plane、sohara-dashboard(UI 资源,可并入前两者);D5b 时增 sohara-nats。