feat: enforce durable queue resource limits and backpressure
This commit is contained in:
75
docs/reports/phase-3-queue-resources.md
Normal file
75
docs/reports/phase-3-queue-resources.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# P3 队列资源控制回归记录
|
||||
|
||||
验证日期:2026-09-17。本阶段完成队列配置、并发降额、开始限速及未终结任务背压。P3 仍需应用级配额、业务键许可、优先级/公平性和可靠订阅;持续目标保持进行中。
|
||||
|
||||
## 1. 已实现范围
|
||||
|
||||
- `POST /v1/queues/{id}:configure` 完整替换暂停、并发、开始速率和未终结任务上限,带授权、CAS、稳定身份、事件和管理审计。
|
||||
- 基于数据库时间的一秒开始计数窗口,多节点共享;Start 事务消费额度,旧回执重报不重复计数,节点更换不清零。
|
||||
- 领取预留尚未开始的窗口空间,满额时保持 WAITING。领取后降额可使 Start 返回 RATE_LIMITED,自动 SDK 保留原消息身份退避核对。
|
||||
- 未终结任务额度涵盖等待、预占、运行和核查;首次受理增加、首次终态减少,重试和迟到证据不重复变更。
|
||||
- 满额受理返回 HTTP 429 / QUEUE_FULL / Retry-After: 1;原已受理请求仍可补取回执。SDK 提供类型化错误及 RetryAfter,不自动重报写请求。
|
||||
- 计划补跑受相同积压上限限制,保留未受理的原触发点;释放空间后按冻结漏跑策略接续。
|
||||
- 迁移 000009 增加四个队列字段并回填既有未终结任务,Go/SQL 均有中文说明,无数据库外键。
|
||||
- 源码核对 257 个直接声明的持久化字段均有中文注释;实体仍为 32 个。
|
||||
- [队列接口与完整 SDK 场景](../api/queues.md)、[resources 示例](../../sdk/go/examples/resources/main.go) 同步交付。
|
||||
|
||||
## 2. 环境及执行结果
|
||||
|
||||
macOS、Go 1.27.1、Docker 单实例 MySQL 8.4.10。使用独立临时数据库、随机凭据及回环端口,结束后清理测试容器,未使用业务数据库。
|
||||
|
||||
```sh
|
||||
make fmt test vet build
|
||||
make integration
|
||||
cd sdk/go
|
||||
GOWORK=off go test -race ./...
|
||||
GOWORK=off go vet ./...
|
||||
```
|
||||
|
||||
全部通过。完整集成后补充了并发开始竞争、Start 回滚、配置作用域及旧库额度回填断言,对 QueueResources 与 SafeRetryUpgrade 重新运行真实 MySQL 竞态回归并通过;修改的测试包再次通过 vet。没有用跳过数据库的普通单元结果代替真实集成证据。
|
||||
|
||||
| 测试组 | 实际结果 |
|
||||
| --- | --- |
|
||||
| 完整 MySQL 集成 | PASS,64.830 秒 |
|
||||
| SDK Worker 全部连接/运行器回归 | PASS,80.819 秒 |
|
||||
| SDK 计划生命周期 | PASS,含包开销 4.579 秒 |
|
||||
| 新增 SDK 资源生命周期 | PASS,3.19 秒,含包开销 4.414 秒 |
|
||||
| 真实服务/Worker 进程故障组 | PASS,21.425 秒,包含新增积压额度强杀恢复 |
|
||||
| 补充资源与升级检查 | PASS,16.228 秒;资源用例 11.00 秒,升级用例 3.85 秒 |
|
||||
| 九个完整示例 | health / tasks / worker-protocol / worker / history / retry / schedules / cancellation / resources 全部通过 |
|
||||
|
||||
上述为测试用时,不是吞吐或延迟指标。
|
||||
|
||||
## 3. 数据库及竞争证据
|
||||
|
||||
[资源集成用例](../../internal/storage/mysql/queue_resources_integration_test.go) 验证:
|
||||
|
||||
- 积压上限为 3 时,16 个并发提交恰好 3 个受理,其余为 QUEUE_FULL;拒绝请求不残留幂等占位,已受理原身份在满额下仍可查询回执。取消后可再次受理。
|
||||
- 两个节点、两个独立 Worker 实例先各领取任务,随后将开始上限从 4 降到 2,四个并发 Start 恰好两个通过,其余限流;任务/许可保留。
|
||||
- 强制 Start 事件写入失败后,任务仍为 LEASED,开始计数为零,原消息可在故障解除后重试。
|
||||
- 跨命名空间及队列范围受限的配置修改被拒,拒绝操作不残留配置身份。
|
||||
- 暂停禁止领取和 Start,但仍可提交与取消;配置同身份返回原快照,旧版本新操作冲突,成功变更各有一条审计。
|
||||
- rate=1 时未开始预留阻止额外领取;Start ACK 重报不重复计数。切换服务节点并 Resume 后窗口仍有效,两次实际 authorized_at 至少相隔一秒。
|
||||
- 从两张在途许可降到并发 1、积压 1,不撤销在途执行;超过上限时不再领取。已领取 Start 限流后,用原消息在下一窗口成功,不增加尝试次数。
|
||||
- 强制任务事件写入失败时回滚积压增加;明确失败后重试保持一个名额,UNKNOWN 耗尽后核查继续占名额;WAITING 截止及重复恢复只释放一次。
|
||||
- 计划在积压 1 下只生成一条任务,游标停在下一原触发点;取消释放空间后下一批准确接续该触发点。
|
||||
|
||||
既有取消、结果 ACK 丢失、许可恢复及计划事务回归同步通过。额外的计数核对直接比较队列 counter 与任务真实状态集合,避免只检查返回 DTO。
|
||||
|
||||
[既有 v4 升级用例](../../internal/storage/mysql/retry_upgrade_integration_test.go) 继续走正式迁移到当前版本,新增验证 WAITING 和 NEEDS_REVIEW 合计回填为 2、默认上限 100000、原队列 revision=1 不变。旧任务各字段、策略、状态及重复迁移检查仍通过。[无外键升级用例](../../internal/storage/mysql/no_foreign_keys_integration_test.go) 同步验证当前外键为零及既有索引保留。
|
||||
|
||||
## 4. HTTP、SDK 和进程恢复
|
||||
|
||||
[SDK 用例](../../sdk/go/queue_resources_integration_test.go) 对真实 HTTP/WS 服务创建独立队列,验证省略 paused 被拒、429/QUEUE_FULL/RetryAfter、满额下重复受理回执、取消释放、原被拒身份重试、暂停期间不消耗尝试、恢复后自动 Worker 完成两个任务及精确整数保留。读取实际开始历史验证 rate=1 的授权间隔,最终 unfinished_tasks=0,运行计数不改变配置 revision。
|
||||
|
||||
[进程用例](../../sdk/go/worker_process_integration_test.go) 的 TestIntegrationWorkerProcessQueueBackpressure 在任务受理后强杀节点 A,Wait 确认退出,再启动不同身份的 B:新提交仍被满额拒绝,原身份仍返回原任务;取消释放后,之前被拒的新任务可用原身份受理。该过程没有修改额度或任务状态来模拟恢复。
|
||||
|
||||
完整资源示例输出 QUEUE_FULL/429、duplicate=true,最终两个任务 SUCCEEDED/attempts=1、unfinished=0、worker_drained=true。业务处理仅回显通用输入,无外部副作用。原有服务强杀、Worker 强杀转核查及两节点调度补跑回归也全部通过。
|
||||
|
||||
## 5. 边界与后续
|
||||
|
||||
一秒计数窗口允许窗口内突发,窗口交界可能出现短时聚集;不保证任意滑动一秒上限。限速针对平台开始授权,不限制业务处理器的内部请求。降低配置不回滚已有外部效果。
|
||||
|
||||
队列积压计数与任务写入在同一事务,直接绕过服务修改数据库可能造成漂移。尚无自动修复计数或硬删除入口;迁移回填要求停止旧服务及写入,未做大表在线回填验收。历史回执新增字段的兼容规则见接口手册。
|
||||
|
||||
当前验证同机进程、多节点身份及单 MySQL,尚未覆盖数据库复制切换、跨故障域、混合版本滚动升级、热点队列吞吐及百万租户容量。应用级配额、同业务键并发许可、优先级/公平性、可靠交付积压限制与保留清理仍需继续实现和回归;本阶段不等于 P3 或平台最终验收完成。
|
||||
Reference in New Issue
Block a user