让你设计一个十万人同时抢一千件商品的秒杀系统,你会从入口到库存怎么设计?
我的判断
秒杀的核心是入口削峰、资格校验、库存原子预扣和异步落单,并让每一步可限流、幂等和补偿。
十万人抢一千件时,我不会让十万请求直达数据库。CDN 承担静态资源,网关校验活动令牌、用户与设备限流;进入秒杀服务后先做活动时间、用户资格和一人一单校验。
库存提前加载到 Redis,Lua 在同一 slot 内原子检查购买标记并扣减,成功才写入有界消息队列:
请求 -> 资格/限流 -> Redis 原子预扣
-> Kafka -> 创建订单 -> 通知结果
消费者按请求 ID 幂等创建订单,数据库对 (activity_id, user_id) 建唯一约束。落单失败通过补偿事件归还 Redis 库存;支付超时由延时任务关闭订单并释放最终库存。客户端查询排队结果,不同步等待整条链路。
容量以峰值而非平均估算,队列长度和 Redis 并发有硬上限。压测会模拟热点 key、消费者停机、重复消息和 Redis 主从切换,并对 Redis 预扣数、消息成功数、订单数、支付数做持续对账。
01用户请求
→02CDN 与边缘防护
→03网关鉴权与限流
→04秒杀接入服务
→05Redis 原子预扣
容易答偏踩坑误区
- 入口只做验证码,不做容量限流。 请求最终仍会压到库存层。
- Redis 扣减成功就算下单成功。 消息与数据库失败需要补偿和对账。
- 所有用户轮询数据库查结果。 应查轻量状态或通过推送通知。