标准答案

  1. 入口按用户和商品限流,拒绝重复请求和明显无资格请求,避免所有流量进入库存库。
  2. 队列任务带用户、商品和幂等键,消费者按商品或库存 Key 控制并发。
  3. 数据库条件扣库存和订单唯一约束保证最终正确;返回排队或处理中时必须提供查询状态。
  4. 处理支付超时、取消、重复消息和库存预扣回滚,定期对订单、库存和支付结果对账。

题目解析

最小秒杀流程要先限制入口和重复请求,再把有效请求写入带幂等键的队列。排队成功只表示请求已经受理,不能承诺库存和订单已经成功。

消费者按商品或库存 Key 控制并发,数据库用条件更新和订单唯一约束裁决库存与订单。缓存可以预扣或拦截明显超量,但必须有回滚、恢复和权威对账。

状态查询要区分 queued、processing、succeeded、sold_out、failed 和 cancelled。支付超时、重复消息、取消和库存预扣回滚都要进入可恢复状态,不能只实现成功路径。

代码示例

最小流程的伪代码:

TypeScript
if (!limiter.allow(userId, sku)) return tooManyRequests()
const accepted = await queue.enqueue({ userId, sku, idempotencyKey })
return accepted ? { status: 202, operationId } : conflict()

// consumer: conditional stock update + unique order + status query

常见误区

  • 误区:前端按钮禁用就认为防重复。改正:服务端使用幂等键、唯一订单约束和状态查询。
  • 误区:缓存扣减成功就直接返回订单成功。改正:缓存只负责削峰,必须等权威库存和订单状态确认。
  • 误区:没有处理排队超时、取消和最终对账。改正:为每种终态和补偿设计持久化记录,并定期核对订单、库存和支付。

作者信息