95 lines
8.1 KiB
Markdown
95 lines
8.1 KiB
Markdown
# P3 应用级配额与跨命名空间回归
|
||
|
||
验证日期:2026-09-17。本阶段补齐应用共享的未终结任务上限、执行并发及开始速率,同步 HTTP、独立 Go SDK、CLI 和双命名空间示例。P3 业务键许可、公平性及可靠订阅,以及 P4–P7 仍未完成,持续目标保持进行中。
|
||
|
||
## 1. 交付范围
|
||
|
||
- [应用配额接口](../api/application-resources.md):读取当前应用额度及用量、显式应用管理权限、CAS/幂等管理、同事务审计和事件、降额保留在途任务。
|
||
- [ApplicationResources 模型](../../platform/model/application_resources.go) 与 000010 前向迁移:12 个持久化字段提供中文注释,SQL 同步 COMMENT,应用主键 BINARY(16),数据库外键仍为零,当前模型共 33 个。
|
||
- 受理、计划生成、领取、Start、取消、Finish、安全重试及到期恢复共同维护应用计数,跨命名空间与队列共享。空轮询与失败受理不消耗计数,重复回执不重复计费。
|
||
- 额度行与认证身份分离,统一按应用额度 → 队列 → 任务/尝试 → 许可顺序取锁;后台扫描跳过忙碌额度,应用停用后仍可释放到期尝试。
|
||
- 管理 CLI 支持 `--application-id` 在已有启用应用下增加命名空间;应用管理权限必须显式 `--resource-access`,普通队列及 Worker 凭据不扩权。
|
||
- [双命名空间 SDK 示例](../../examples/application-resources/main.go):第一侧受理,第二侧 APPLICATION_FULL,第一侧取消释放,第二侧原身份重报成功,取消收尾并按 CAS 恢复配置。
|
||
|
||
## 2. 环境和实际回归
|
||
|
||
macOS 本机,Go 1.27.1,Docker MySQL 8.4.10;服务进程与数据库仅监听回环地址。使用随机凭据及一次性数据库,测试结束删除测试容器,没有修改已有业务数据库。
|
||
|
||
执行入口:
|
||
|
||
```sh
|
||
make fmt test vet build
|
||
make integration
|
||
```
|
||
|
||
完整集成通过。测试分组的本次结果:
|
||
|
||
| 分组 | 结果 |
|
||
| --- | --- |
|
||
| 全部数据库集成(含模型、无外键、配额、计划、执行及竞争) | PASS,68.475 秒 |
|
||
| v9 应用计数回填与在途释放 | PASS,3.94 秒 |
|
||
| v7 无外键升级、索引及数据保留 | PASS,3.85 秒 |
|
||
| SDK Worker 连接、运行器、重试、取消和断线处理 | PASS,78.509 秒 |
|
||
| SDK 计划生命周期 | PASS,含包开销 4.733 秒 |
|
||
| SDK 队列资源控制 | PASS,含包开销 4.456 秒 |
|
||
| SDK 双命名空间应用配额 | PASS,含包开销 1.401 秒 |
|
||
| 原有真实进程故障组 | PASS,23.638 秒 |
|
||
| 十个可运行示例 | 全部通过 |
|
||
|
||
十个示例为 health、tasks、worker-protocol、worker、history、retry、schedules、cancellation、resources、application-resources。上述用时仅为回归耗时,不是吞吐或容量结论。未配置集成环境的普通 `go test` 会跳过外部数据库及进程用例,实际证据来自已执行的集成入口。
|
||
|
||
本轮发现原计划版本边界用例使用宿主机时钟等待,而服务按数据库时间判定。用例改为从 MySQL 时间建立边界并等待真实数据库时刻,保留原版本、触发身份和结束状态断言;完整数据库回归随后通过。
|
||
|
||
## 3. 配额与事务证据
|
||
|
||
[数据库用例](../../internal/storage/mysql/application_resources_integration_test.go) 覆盖:
|
||
|
||
1. 普通队列凭据读取及管理应用额度被拒绝;显式授权后同应用另一个命名空间可读聚合额度,其他应用保持独立。
|
||
2. 配置 CAS、同身份原快照重报、内容冲突;审计故障注入使配置、事件及幂等记录一起回滚,恢复后原身份可成功提交。
|
||
3. 两个命名空间各自队列同时发起 16 次受理,上限为 3 时仅 3 次成功;满额原成功回执仍可核对。降额至 1 不删已有任务,逐项取消后重新受理。
|
||
4. 队列已满和事件写入失败均不能泄漏应用额度;应用与队列计数同时回滚,原请求可以重报。
|
||
5. 两个节点/命名空间争用应用并发 1,仅一个取得尝试;预占取消释放未开始额度,成功结果及重复 Finish 不重复释放。
|
||
6. 预占后降低并发及开始速率,已有尝试保留;Start 事件故障回滚用量;原 Start ACK 重报不收费;未开始的预占跨窗口保留,不能被其他任务抢占。
|
||
7. 明确失败重试不重复占用积压,已开始失联保留未知效果及未完成额度,未开始到期和待执行截止释放空间。应用停用不阻止后台回收执行额度。
|
||
8. 定时计划遇到应用满额时保留未受理触发点,已生成的批次部分提交;释放空间后恢复同一原触发点,两级计数一致。
|
||
9. 一个应用额度行被显式持锁时,另一应用的恢复仍能推进;缺失、停用或参数歧义的应用不能由初始化 CLI 创建新命名空间。
|
||
|
||
所有计数断言同时查询真实任务状态进行核对,不只断言接口里的同一计数字段。
|
||
|
||
## 4. 迁移和无外键
|
||
|
||
[应用额度升级测试](../../internal/storage/mysql/application_resources_upgrade_integration_test.go) 在隔离库建立有效任务、尝试、Worker 会话和许可,然后还原为 v9 结构再运行正式迁移:
|
||
|
||
- 同一应用两个命名空间包含 WAITING、LEASED、RUNNING、NEEDS_REVIEW 和已成功任务,回填为 unfinished=4、active=2、pending=1;成功任务排除在外。
|
||
- 空应用三个用量均为零,配置默认值、版本与空窗口正确。
|
||
- 历史任务状态及版本不变;重复执行迁移不重算或覆盖当前计数。
|
||
- 迁移前已存在的预占取消和运行尝试完成后,共享用量正确变为 unfinished=2、active=0、pending=0。
|
||
|
||
v4 升级继续核对冻结策略、未知标记及应用未完成数。v7 无外键升级仍移除全部 70 个历史外键,已有 325 条索引列定义保留;新应用额度表自身主键另计。错误队列归属、错误会话关系及手工外键漂移继续被拒绝。
|
||
|
||
## 5. SDK 与进程验证
|
||
|
||
[SDK 集成用例](../../sdk/go/application_resources_integration_test.go) 通过实际 HTTP 验证两个命名空间共享配置、普通队列管理员无应用权限、跨命名空间幂等键空间独立、错误字段及应用归属覆盖被拒绝。第二侧收到 HTTP 429 / APPLICATION_FULL / Retry-After: 1;第一侧释放后,原键提交成功,最终三个用量为零。
|
||
|
||
示例实际输出:
|
||
|
||
```text
|
||
cross_namespace_backpressure=APPLICATION_FULL http=429
|
||
same_identity_retry_accepted=true
|
||
unfinished=0 active=0 pending_starts=0
|
||
```
|
||
|
||
原有服务 ACK 丢失接管、Worker 强杀后未知核查、计划强杀补跑和队列背压进程用例同步通过。
|
||
|
||
最后定向回归新增的额度泄漏断言与应用强杀场景也通过:数据库应用配额九组场景 10.24 秒(含包开销 11.572 秒),SDK 应用配额 0.15 秒,完整示例再次通过;`TestIntegrationWorkerProcessApplicationBackpressure` 0.14 秒(含包开销 1.818 秒)。该场景强杀并 Wait 确认旧服务退出,再启动不同 node_id:共享上限和未完成计数保留,原受理回执可重放,另一个命名空间继续被全局满额拒绝,原任务取消后才能用被拒原键受理。这项证明应用受理额度跨进程持久化,不将它扩大为全部数据库故障模型或开始速率窗口的进程验收。
|
||
|
||
文档校验通过 320 个本地链接及 26 个 JSON 示例;269 个直接声明的持久化字段全部有中文注释。
|
||
|
||
## 6. 当前边界
|
||
|
||
- 共享配额限于同一 MySQL 主库。单个应用的额度行是串行化点,必须在生产容量阶段测锁等待、吞吐、续租与恢复延迟;没有宣称百万租户容量或跨库原子配额。
|
||
- 开始限流为固定一秒窗口,允许边界突发;控制的是平台授权次数,不是处理器内部业务请求。
|
||
- 停止旧写入节点后迁移再启动新版,不能与不维护应用用量的旧节点混跑。大表回填和混合版本在线升级未验收。
|
||
- 数据库关联依靠服务端事务,没有外键;直接 SQL 修改归属或删除额度记录不属于支持的业务操作。
|
||
- 本轮为单数据库、多服务进程及故障注入验证;数据库复制切换、跨故障域网络分区、备份恢复、实际 RPO/RTO 和峰值容量仍在 P6。
|