6.1 KiB
6.1 KiB
P3 事件消费 SDK 与节点故障回归
验证日期:2026-09-17。已交付 消费 SDK 和 协议示例。业务端持久化 Inbox 示例及消费者进程强杀恢复尚未完成,P3 和持续目标继续进行。
1. 实现范围
- EventConnection:严格事件协议、接收、请求关联、ACK、心跳和关闭;控制最多32个在途,接收缓冲为声明容量,超时关闭连接后保留原证明核对。
- EventConsumer:自动心跳、指数退避重连、本地1–32个在途事件、成功后确认、ACK不明时原证明核对、处理器失败不确认、取消与有界收尾。
- 类型及秘密隐藏:ResultEvent不给业务处理器租约秘密;Grant/Proof仍可显式序列化用于受保护的存储,普通fmt隐藏敏感数据。
- 严格解码:大小写、重复键、方向、会话、规范uint64、证明编码和事件/交付/快照关联。大整数不经float64转换。协议类WebSocket关闭按永久错误处理。
- 协议例子:产生取消结果、读取、ACK、重连重报、验证原确认时间、暂停订阅。它只读取结果,不执行接收方业务写入。
- SDK保持独立模块,无新增数据库驱动、服务端包或持久化模型。本阶段不增加迁移、外键或级联删除。
2. 验证环境与入口
macOS、Go1.27.1、Docker MySQL8.4.10、一次性数据库;普通SDK集成连接真实Orbit进程,故障网关使用本地TLS,进程回归使用真实子进程和SIGKILL。注入后用Wait确认进程已经退出,不能以发送了Kill调用代替终止证据。
make fmt test vet build
make integration
cd sdk/go
GOWORK=off go test -race ./...
| 分组 | 结果 |
|---|---|
| 全量MySQL集成 | PASS,92.995秒 |
| SDK Worker连接/运行器 | PASS,88.494秒 |
| SDK计划、队列、订阅管理、应用配额 | PASS,5.704 / 4.466 / 33.386 / 1.363秒 |
| 新消费SDK三项集成 | PASS,2.18 / 15.28 / 33.14秒,包总计51.843秒 |
| 新节点交付租约恢复 | PASS,32.15秒 |
| 新ACK提交/丢响应/节点强杀 | PASS,1.31秒 |
| 九项真实进程故障(原七项加新两项) | PASS,包总计61.810秒 |
| 完整SDK示例 | 14个全部通过,包括新的event-protocol |
| fmt、race、vet、build | PASS |
| GOWORK=off独立SDK模块 | PASS,编译及竞态测试不依赖服务端workspace |
完整SDK示例输出包含:
event=<本次事件ID> task=<本次任务ID> state=CANCELLED
ack_replayed=true same_receipt=true pending=0 subscription_enabled=false
3. 协议与运行器边界
连接单元回归 在TLS服务器上混合投递与乱序控制响应,验证独立关联、精确数字、秘密隐藏;取消Next不关闭连接,已发ACK取消关闭连接并报告未知确认状态。32个控制槽满后拒绝新控制,交付缓冲满后关闭。拒绝重复键、大小写别名、非规范计数、null布尔/错误、缺失创建时间、错误事件关联、状态不匹配、额外字段及不匹配ACK;1008关闭不无限重连。
运行器回归 验证ACK回应丢失后原证明重连,不重复运行仍保留的已提交处理器;新代次替换后重新进入业务去重;error/panic/Goexit均不确认、不立即本地重试。取消后收集已提交结果,忽略取消的处理器在收尾期限到达后报告Running与Unconfirmed。永久401只连接一次,实例不能重复Run,容量2实际并行处理并限制并发。
处理器测试中的原子计数只用于确认调用次数,不能作为已实现持久化Inbox的证据。
4. 真实服务与MySQL
- 接收已取消任务的冻结快照,暂停后Ping返回enabled=false,已有Proof仍能ACK;关闭连接后重报返回同一确认时间。暂停时新增结果不投递,恢复后继续消费,最终pending_count=0。
- 处理器持续等待真实15秒自动心跳,故障网关收到上游心跳ACK才放行业务完成。随后上游提交事件ACK,网关丢弃回应并断开。消费器重连核对原证明,处理器调用数和交付次数均保持1。
- 首次处理器返回error,SDK不ACK。测试等待服务端真实30秒租约及退避,不修改数据库时间;同一交付以第二代次发送,处理成功后确认,最终attempts=2、HandlerFailures=1。
5. 真实节点强杀
- 领取提交后节点退出:节点A成功投递后被SIGKILL并确认退出。节点B读取同一MySQL,在租约自然到期后恢复相同event_id/delivery_id,代次和次数增加到2。旧Proof返回DELIVERY_LEASE_LOST,新Proof成功ACK,订阅积压清零。
- ACK提交后响应丢失:网关截获成功ACK回应并阻断后续重连;通过查询确认ACKED和已保存的确认时间,然后强杀节点A。启动节点B,切换网关并恢复连接;Consumer仍持有原Proof,返回原确认时间,不新建交付尝试,不重跑处理器。
这两项强杀的是Orbit服务端进程。第二项消费器保持运行,其内存证明未丢失;不能将此证据当作消费者进程被强杀后业务去重也已验证。
6. 保留边界
- 后续需要交付独立业务数据库的Inbox事务例子,验证提交后/ACK前消费者进程退出、并发重复投递以及接收方事务回滚/提交不明等窗口,再验收P3可靠订阅。
- Consumer取消或传输断线不能撤销已经发出的业务效果;交付租约不是业务互斥锁。生产业务需要持久化唯一键和事务,外部副作用需要业务幂等/Outbox/核查。
- 当前仍按启用订阅的领取活动恢复过期交付;独立清扫、历史保留与清理、凭据安全重绑和生产容量/RPO/RTO仍属后续阶段。
- 结果证明只覆盖本报告的单数据库、进程/TLS网关拓扑;未将本机回归等同于百万租户容量或生产高可用验收。