5.6 KiB
通用资源退役
适用于长期服务、临时环境和自动化回归。平台不根据应用名称、队列名称或测试前缀自动清理。退役是不可恢复的显式管理动作,保留资源 ID、名称、任务、交付、幂等回执与审计;不是硬删除,也不自动归档或缩小数据库。
接口与权限
| 操作 | HTTP | 权限 | Go SDK |
|---|---|---|---|
| 退役订阅 | POST /v1/subscriptions/{id}:retire |
events:manage,原凭据所有权和队列授权 |
RetireSubscription |
| 退役队列 | POST /v1/queues/{id}:retire |
queues:manage 和队列授权 |
RetireQueue |
单管理员通过已登录的控制台管理授权范围;普通 SDK 不能操作其他凭据的订阅。请求需要 Bearer 身份及 Idempotency-Key,不接受查询参数,正文:
{"expected_revision":"3","reason":"临时资源已结清,结束使用"}
成功 HTTP 200,保持现有 request_id + data/error 信封。data 分别为 {subscription,deduplicated}、{queue,deduplicated}。查询及列表增加可选 retired_at;订阅同时增加十进制字符串 retired_sequence。旧记录不需要回填。
同键同内容返回原回执,不因状态已经退役而失败;同键不同内容为 IDEMPOTENCY_CONFLICT。无明确回执时必须保存并重用原目标、请求和键,不自动生成新键。新命令须携带最新配置 revision。
订阅的结清边界
退役事务锁定命名空间结果流的已提交水位,再锁订阅。必须同时满足:
- pending_count=0,实际不存在 PENDING、LEASED 或 EXPIRED 交付。
- 截止水位之前,没有该队列和类型过滤范围内尚未物化的结果;缺失来源或历史保留缺口也拒绝退役。
成功后 enabled=false,记录退役水位并推进 cursor 至该水位,释放一个活动名额。此后新产生的事件不再属于该订阅。管理员应先停止旧生产者并排空消费者;平台无法判断调用方将来是否还会提交任务。
暂停依然占活动名额;每命名空间最多 64 个未退役订阅。已退役记录仍可列表、读取和查交付历史,不能恢复、重置起点或更换原名称。不存在通过忽略未消费事件强制释放名额的接口。
队列的依赖保护
队列退役按应用额度、操作身份、队列持锁,与提交、执行和流程推进串行。下列情况返回 RESOURCE_BUSY 并说明原因:
- 有未完成或待核查任务、在途执行尝试或未释放执行许可。
- 有启用的定时计划。先暂停计划,已产生任务仍须结清。
- 有固定版本引用该队列的未终结流程,包括暂停、等待、尚未执行到该队列的分支。
- 有未退役订阅,包括暂停订阅。
成功后 paused=true,禁止新任务、新订阅、Worker 注册、计划创建/发布/恢复以及使用该队列启动新流程。已发布流程定义和暂停计划作为历史保留,不能绕过退役恢复新工作。任务与流程历史查询继续可用,原已完成命令的冻结回执不重写。队列名称不回收,重新使用需创建新 ID 和名称。
SDK 与自动化收尾
使用 git.yuntuo.hk/k2safe/orbit/sdk/go@v0.1.2;旧 v0.1.1 消费/提交协议继续兼容,但不包含新方法。当前仓库内可直接从 sdk/go 运行示例。
sub, err := client.GetSubscription(ctx, subscriptionID)
if err != nil { return err }
// 实际服务应把 key 和请求持久保存,未知回执重放原内容。
retire := orbit.RetireResourceRequest{
ExpectedRevision: sub.Revision,
Reason: "临时资源已经结清",
}
_, err = client.RetireSubscription(ctx, subscriptionID, stableOperationKey, retire)
if err != nil { return err } // RESOURCE_BUSY 时先排空/核查,不能跳过结果。
queue, err := client.GetQueue(ctx, queueID)
if err != nil { return err }
_, err = client.RetireQueue(ctx, queueID, stableQueueOperationKey,
orbit.RetireResourceRequest{ExpectedRevision: queue.Revision, Reason: "停止使用队列"})
return err
建议顺序:停止生产者和计划 → 结清执行与流程 → 消费并确认所有订阅结果 → 退役订阅 → 退役队列。失败的测试可能保留待核查任务,收尾应报告资源 ID 与阻塞原因,不能把测试失败变成丢弃结果的理由。
完整可运行示例:resource-lifecycle。示例只操作本次新建空资源;进程异常终止仍可能留下资源,需要按输出 ID 核查,不能无限创建来绕过名额。
错误和管理页面
| HTTP / code | 含义 |
|---|---|
409 RESOURCE_BUSY |
尚未结清,message 给出依赖或积压原因;状态不变 |
409 RESOURCE_RETIRED |
新命令试图复用已退役资源 |
409 STATE_CONFLICT |
配置版本不匹配 |
409 IDEMPOTENCY_CONFLICT |
原键对应不同内容 |
410 EVENT_HISTORY_EXPIRED |
订阅存在无法验证的历史缺口 |
| 401 / 403 / 404 | 保持现有身份、权限和资源隔离语义 |
控制台“结果订阅”详情提供退役入口;“应用接入”提供所选队列退役和活动订阅名额。多队列时明确选择,浏览器只记忆命名空间对应的队列 ID;暂停/退役状态清晰展示。复制配置不会静默换成另一张凭据有权限的队列。
部署与保留
先停止旧写节点,再执行迁移 000034,再启动新版本;不要混跑不认识退役状态的旧服务端。现有资源默认未退役,不自动处理任何应用或测试数据。新库基线仍为零外键。历史保留、归档导出继续按现有配置执行;本次退役不引入自动删除机制。