Files
orbit/docs/sdk/production-integration.md

5.3 KiB
Raw Permalink Blame History

生产接入闭环

这份手册把 SDK、HTTP 查询和 WebSocket 结果通知串成一条可落地的接入链路。它只描述平台协议,不包含任何业务系统名称、行业规则或外部副作用。

完整可运行的业务宿主见HTTP 服务示例,可复用事务能力见MySQL Outbox 包。

1. 接入边界

业务服务保存操作身份和请求正文,再调用 SDK 提交。Idempotency-Key 必须由业务库或 Outbox 持久化,网络超时、进程重启和响应不明时复用原键;不能生成新键猜测服务端是否已提交。受理回执只表示平台已经保存请求,不能当作任务或流程完成。

api, err := orbit.NewClient(baseURL, orbit.Options{Token: token})
if err != nil { return err }

// operationKey 与请求正文一起写入业务库;重试始终复用它。
receipt, err := api.SubmitTask(ctx, operationKey, orbit.SubmitTaskRequest{
    QueueID: queueID, Handler: "file.convert", HandlerVersion: "v1",
    PayloadVersion: "v1", Payload: json.RawMessage(`{"source_ref":"objects/input.csv"}`),
    RecoverySafety: orbit.RecoveryReconcileOnly,
})
if err != nil { return err }
taskID := receipt.Task.ID

凭据只授予调用方所需的命名空间、队列和动作范围。生产使用 HTTPS;SDK 不负责 TLS 终止、密钥托管或外部业务核查。所有 API 错误都保留 RequestID、稳定错误码和 HTTP 状态,日志不得写入 Token、完整业务键或结果正文。

2. 完成通知与权威查询

结果通知使用 Event WebSocket。连接时声明 orbit.events.v1 子协议和允许的来源,SDK 自动发送心跳、在连接断开后重连,并把上一次未确认的投递证明带回新连接。自动消费器的处理器完成业务事务后返回 nil,SDK 再发送 ACK;处理器失败或进程在提交前退出时不要确认,平台会在租约到期后重投同一交付。

consumer, err := orbit.NewEventConsumer(api, orbit.EventConsumerOptions{
    SubscriptionID: subscriptionID,
    Capacity:       8,
    Handle: func(ctx context.Context, event orbit.ResultEvent) error {
        // 先按 event.ID 持久化去重,去重与业务更新在同一事务确认后返回 nil。
        return applyOnce(ctx, event)
    },
})
if err != nil { return err }
if err := consumer.Run(ctx); err != nil { return err }

通知只推动业务侧再次读取权威状态。收到 task.completed、workflow.stopped 或 workflow.review_required 后,调用 GetTask、GetWorkflow 或对应历史接口;事件快照不替代当前状态,也不表示外部效果已经完成。没有 WebSocket 时可以使用有界 HTTP 查询作为兜底,但必须使用退避、截止时间和业务键,不得无限轮询。

3. 流程实例的恢复顺序

流程进入 NEEDS_REVIEW 后,接入方按下面顺序处理:

  1. 读取当前实例、当前步骤、相关任务和外部证据,保存当时的 revision、步骤 revision 与 activation_id。
  2. 使用对应恢复方法提交一个有证据的决定:任务核查、步骤结论、步骤重试、PENDING 接续或等待重建。
  3. 等待内部结果被消费,再重新读取实例和步骤;不要把恢复回执快照当作实时状态。
  4. 所有核查事项完成后提交 ContinueWorkflow,如果实例仍暂停,再单独提交 Resume。
  5. 使用恢复回执的 audit_id 查询操作审计,记录操作者、原因、证据引用和前后状态。

STATE_CONFLICT、UNAVAILABLE 或响应未知时保留原请求体和原幂等键,先用相同身份核对;不要把版本刷新后重放成另一种决定。服务端会检查流程版本、步骤版本、激活代次、任务归属、未确认结果、预算和截止时间。

4. 错误处理约定

情况 接入方动作
HTTP 超时、连接断开、响应未知 保留原键和原请求,查询或用原键重报;不生成新键
STATE_CONFLICT 重新读取当前事实和审计,确认是否已有新结果;不能盲目覆盖
UNAVAILABLE / readiness 503 保留业务 Outbox,等待服务恢复;不能把故障改写为任务失败
QUEUE_FULL / APPLICATION_FULL 按业务退避或转人工,保留原身份;释放前不要无限加并发
NEEDS_REVIEW 进入证据核查流程;禁止自动重试未知外部效果
WebSocket 断线 不确认未完成处理;让租约自然重投,并使用交付证明去重

SDK 的 revision、sequence 和游标使用字符串 JSON 编码或 uint64,业务侧不得转成浮点数。结果正文使用 json.RawMessage 保留精确数字;大正文传对象引用并在业务侧设置独立保留和访问策略。

5. 上线前清单

  • 固定服务端版本和 git.yuntuo.hk/k2safe/orbit/sdk/go 的 SDK 版本,执行 go mod verify。
  • 运行 make protocol-check、make sdk-check 和对应版本的真实 MySQL 集成回归。
  • 持久化提交键、恢复键、业务 Outbox 和消费 Inbox;演练提交回执丢失、进程强杀和 WebSocket 重连。
  • 为 /health/live、/health/ready 和独立 /metrics 配置内部监控;确认告警不会自动改写业务状态。
  • 验证凭据轮换、权限撤销、备份恢复、MySQL 切换和容量阈值,再进入生产审批。