AI SaaS 运行时权益快照:让长任务、授权与缓存保持一致
合同或账单迁移生效后,各执行节点仍要得到一致授权。本文用单调权益修订、请求快照与缓存失效处理 Webhook 乱序、长任务和实时撤权。
本文要点
- 主题聚焦:AI、DevOps、独立开发
- 适合人群:独立开发者、全栈工程师、AI 应用开发者
- 核心价值:快速理解背景、实践路径、常见误区和工程建议
用户刚升级 Pro,前端已显示成功,模型网关却仍按 Free 拒绝;另一个用户降级后,已排队两小时的 Agent 继续使用高级模型;Webhook 乱序又把新套餐覆盖回旧状态。这些问题不是“缓存刷新慢”这么简单,而是系统没有定义哪份订阅事实在什么时间产生哪些权益,以及一次运行应绑定哪个版本。
AI 定价迁移 负责合同、价格、cohort 和账单 schedule,AI 平台租户配额 执行资源限额。本篇只拥有 entitlement 控制面:消费已生效商业事实,把它投影为模型、上下文、并发、导出和支持级别等运行时授权快照。
套餐和权益都采用不可变版本
不要修改 pro 这一行让所有历史客户瞬间变化。每次商业定义变更创建新的 planVersion,列出 feature、模型层级、包含单位、超额策略、并发、上下文上限、数据保留和支持权益。订阅实例引用版本,并记录 effectiveFrom/effectiveTo、试用、add-on、grandfather cohort 与人工 override。
{
"snapshotId": "ent_01J...",
"accountId": "ac_42",
"revision": 184,
"planVersion": "pro-2026-07",
"effectiveAt": "2026-08-01T00:00:00Z",
"features": {
"modelTier": "advanced",
"monthlyIncludedUnits": "500000",
"maxConcurrentRuns": 5,
"dataExport": true
},
"source": { "subscriptionId": "sub_9", "eventId": "evt_7" },
"policyDigest": "sha256:..."
}
权益数量使用整数单位,货币和价格不塞进运行时快照。override 必须有原因、批准人和到期时间,不能成为永久隐藏套餐。plan、订阅、add-on 与 override 合并顺序固定并版本化,相同输入必须生成相同 snapshot hash。
Webhook 是通知,不是有序事实流
计费平台可能重复、延迟或乱序投递事件。consumer 按 provider event ID 去重,收到通知后读取或验证当前订阅对象,再由本地事务生成单调递增 revision;旧 effective time 或旧 source state 不能覆盖新快照。立即升级、期末降级、暂停、取消和试用结束分别建明确生效点,不用“最后收到的事件赢”。
写入订阅状态、权益 snapshot 和 cache invalidation outbox 属于同一事务。下游缓存键为 (accountId, revision),别只用 account ID 加任意 TTL。失效消息重复无害,节点观察到 revision 184 后拒绝应用 183。若订阅同步失败,高风险付费写功能 fail closed;短时间保留 last-known read 权益必须有最大陈旧期和告警。
请求和长任务明确绑定快照
网关从可信账户上下文解析 snapshot,不接受客户端自报 plan=pro。每个 operation 保存 entitlementRevision、plan version 和 policy digest;执行器验证 feature 与限额后才创建资源。普通请求在开始时固定快照,避免一次流式响应中途改变模型或价格口径。
长任务需要把规则拆开:已承诺的计费单元、模型档和输出上限通常绑定准入时快照;安全封禁、账户停用和权限撤销实时生效;套餐降级是否允许已运行任务完成由合同明写。任务恢复时加载原 revision,同时查询 live revocation,不得只读一个陈旧 JWT。长任务 Agent 工作流 的检查点应保存这两个版本。
升级后新 operation 可以立即使用新权益;降级在期末生效时,新快照提前创建但只在 effectiveAt 激活。时钟统一 UTC,边界比较由服务端完成。运行跨越账期时,实际 usage 仍按事件发生时间与绑定合同结算,不能为了实现方便全部归到结束日。
Entitlement 与 feature flag 做交集
Entitlement 回答“客户买了什么”,feature flag 回答“代码是否向这批用户发布”。最终允许条件应为 entitled && rollout_enabled && policy_allowed。OpenFeature provider 可以承载 rollout,但 flag 不能把未购买功能授予随机实验桶,也不能在回滚 UI 时删除客户合同权益。AI Feature Flag 的实验上下文还需包含 snapshot revision,便于解释为何同账户结果不同。
指标记录有限 plan version、feature、decision 和 stale class,不把 account ID 作为标签。审计保存输入 revision、合并规则、decision、缓存节点和 operation ID,客服才能回答某次拒绝到底来自未购买、未发布、额度耗尽还是安全策略。
用乱序和时间边界验收
测试重复 Webhook、先取消后收到旧升级、期末 schedule、试用过期、override 到期、缓存节点离线、任务跨降级、账户封禁和回滚旧 policy。断言 revision 在回滚时仍递增、同一时刻只有一个活动快照、flag 不能越权、已绑定 operation 口径不漂移。用固定时钟回放整个订阅周期,而不是等待真实月份。
新 resolver 先影子计算 decision,与旧系统逐请求比较;按 feature 切换而非一次替换全部权益。异常时可恢复旧 resolver 镜像,但 snapshot alias 绝不倒退:追加更高 revision,policy body 指向上一批准版本,并记录 supersedes、新 effectiveAt 和回滚原因,再按正常 outbox 发布。已生成历史不删除,live revocation 也不能随商业回滚撤销。已排定的错误套餐变更应取消 schedule 或追加更正版本,不能原地篡改。权益一致性的目标不是所有缓存瞬间相同,而是每个决定都能指向唯一、有效且单调演进的商业快照。
延伸阅读
Related