MTS / SMTS · 线上 Technical Interview 第二轮

Salesforce 昂贵 API 月度限额:用户配置、原子预占与跨月口径

Salesforce MTS 技术面经问 expensive API 的用户可配置每月限额;本文从计数语义、并发预占、幂等、配置变更和故障降级设计可实现方案。

题目重点:Salesforce MTS 技术面经问 expensive API 的用户可配置每月限额;本文从计数语义、并发预占、幂等、配置变更和故障降级设计可实现方案。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练方案按 user_id 设自然月调用次数上限,月界统一使用 UTC;真实产品可按客户账单时区,但必须固定并展示。限额计‘被接纳且开始执行的逻辑请求’,下游失败也计一次,客户端重试同一 idempotency key 不重复计。
  • 用户可在平台允许的最大值以内修改自己未来调用的限额;本月已使用量不因修改而清零。若降低到低于当前 used,则立即拒绝后续新调用。
  • 每次 API 调用的成本近似一次单位;若成本按 token、执行秒数或第三方费用波动,应改为预算预留与结算,题目未明确这一变体。

解题路线

  1. 明确配置 API 与调用路径:PUT /users/me/monthly-limit 写 limit 和 version,GET /users/me/usage 返回 period、used、limit、remaining;昂贵 API 请求带 idempotency key。配置更新需授权、审计和上限校验,不能让任意用户取消平台保护上限。
  2. 用 (user_id,period) 作为用量主键,period 由固定时区的请求接纳时间计算。数据库保存 limit 配置与 usage 行;一次事务中先查幂等键是否已有结果,再锁定/条件更新 usage,只有 used<当前有效 limit 才把 used 加一并记录 reservation。并发请求必须通过同一个原子写入竞争,不能读后在应用内加一。
  3. 预占成功后才调用昂贵下游;返回成功或失败均把逻辑请求的响应状态写入幂等记录,重复请求返回已有结果或进行中状态。进程在预占后崩溃时保留 reservation 并由恢复任务判定是否已发起下游;若无法判定,偏向防重复执行并提供人工核查,而不是盲目退款或重跑。
  4. 超限返回可解释错误和剩余额度、下次重置时间;配置变化与用量需保留审计事件。若数据库不可用,昂贵 API 默认拒绝或排队,避免丢失计数时无限放行;若业务要求高可用,再讨论有限本地预算与对账的风险。

手动走一遍

训练例:用户在 UTC 10 月限额设为 100,当前 used=99。两个并发请求分别带不同幂等键,只有一个能把 used 从 99 原子改到 100,另一个收到超限。成功请求因网络超时被客户端同键重试,幂等表识别为同一逻辑请求,不再加一次。用户随后把限额调到 80,本月 used 仍为 100,新请求继续被拒;11 月有独立 usage 行,从 0 开始。

规模与取舍

单次调用的配额判定是常数次索引查询/条件更新,应用层时间可视为 O(1),吞吐上限由同一用户的热点 usage 行和数据库事务能力决定。示例若 100 万用户每月限额各 100,理论上最多 1 亿次接纳调用/月、平均约 39 次/秒,但实际峰值、用户分布与昂贵 API 耗时更重要;数字是训练假设。高并发热点用户可用 Redis 原子脚本预占并异步落账,但必须说明缓存丢失、持久化和双写一致性成本。

易错点与追问

容易失分的边界

  • 先读取 used 再无锁递增,两个并发请求都看到 99 而同时越过 100 上限。
  • 把配置版本加入 usage key 且修改限额时新建计数器,导致用户通过改配置重置本月已用量。
  • 用服务器本地时区算月份,跨节点或夏令时造成重置不一致。
  • 重试请求换了幂等键或没有幂等记录,网络超时后再次扣额并重复调用下游。
  • 配额存储故障时默认无限放行,与保护 expensive API 的目标相冲突。

继续深挖

  • 若用户可以按项目或 API key 分配子预算,怎样处理父用户总额度与子额度的原子双层预占?
  • 若下游按实际 token 或 GPU 秒收费,如何做估算预留、最终结算与超预算中止?
  • 若要求失败请求不计额度,怎样安全退款并防止调用方通过故意触发失败无限占用资源?
  • 若每月重置要按客户时区执行,如何处理夏令时、时区修改和跨区域请求?
✓已复制微信号!