Lesson 0012 · 系统设计 · Phase 3 权衡 · 综合案例
大案例 II:秒杀系统
与你的 Mission 的关系
秒杀是「正常架构的全部假设都被打破」的场景:流量 100 倍、库存是热点中的热点、错一批就是真金白银。它把 L5 的缓存、L7 的队列、L10 的三件套全部逼到极限,是面试区分「会用组件」和「会做权衡」的试金石。工程参照:美团技术团队的秒杀实践[1]。
§1 · Step 1澄清需求
| 类别 | 关键约束(要主动确认!) |
|---|---|
| 业务 | 1 万件商品、预计 100 万人抢、开抢时间固定 20:00。铁律:绝不允许超卖;可以少卖(库存回补机制兜底) |
| 公平性 | 要不要绝对先到先得?(机器人面前没有公平——风控是不是需求?) |
| 体验 | 没抢到给明确结果(秒杀的差评大头是「一直转圈」);下单后 15 分钟不支付 → 回补库存 |
§2 · Step 2估算:极端在哪里
- 点击洪峰:100 万人会在开抢前 30 秒内集中点击,页面请求峰值 = 日常的 100 倍以上;
- 下单洪峰:假设 50% 的人点「立即抢购」→ 50 万请求挤在 ~10 秒内 → 下单 QPS ≈ 5 万(对比 Lesson 0002 的量级感:单机 DB 安全线 ~1 万);
- 热点极端化:全部流量打在同一行库存记录上——Lesson 0005 的热 key 与 Lesson 0006 的倾斜在最坏形态下同时出现。
结论:常规「请求 → DB 扣库存」在数学上就不成立,必须让绝大多数请求到不了 DB。
§3 · Step 3高层设计:漏斗逐层放行
100 万用户
│ ① 静态化 + CDN:商品页全静态,详情/倒计时都别回源(L3)
▼
│ ② 按钮后置 + 前端限流:开抢前按钮禁用,点击后 5 秒内不可重复
▼
│ ③ 网关限流 + 风控:全局限流 5 万 QPS(L10),机器人/黑名单直接拒
▼
│ ④ Redis 预扣库存:Lua 原子「查+扣」,扣不到直接返回「已抢完」
▼ ←—— 90%+ 的请求死在这里,DB 无感
│ ⑤ 消息队列:扣减成功 → 发「抢购成功」事件(L7),立刻返回「排队中」
▼
│ ⑥ 订单服务消费:落库创建订单(DB 行级扣减此时只承担 1 万笔)
▼
└── ⑦ 15 分钟未支付 → 超时回补库存(延迟消息)
本设计的灵魂一句话
把「抢」挡在 Redis,把「卖」放进 MQ,DB 只负责最终成交的那 1 万笔。漏斗每层的「拒绝率」就是每层的价值。
§4 · Step 4深入与权衡
| 深挖点 | 讨论 |
|---|---|
| 为什么不超卖? | Redis 预扣用 Lua 脚本把「读库存-1-写回」做成原子操作(单线程模型天然串行),扣到负数直接拒绝。应用层先读后写在并发下必然超卖(check-then-act 竞态) |
| Redis 扣了、MQ 丢了怎么办? | 少卖了(库存没释放)。接受 or 修补:本地消息表/事务性 outbox 先落库再发事件(L7 幂等延伸)。权衡:秒杀场景「少卖可容忍、超卖不可容忍」——不对称代价决定不对称设计 |
| 用户视角的一致性 | 预扣成功 ≠ 订单已创建。前端轮询「抢购结果」接口(读订单创建状态),明确告知「排队中/成功/失败」——不确定状态要给出口,别让用户无止境等待(L9:此处接受最终一致) |
| 幂等 | 用户连点/前端重试 = 同一用户重复请求 → 请求带 userId+活动 ID 幂等键,Redis SETNX 拦截重复预扣(L7) |
| 降级预案 | Redis 挂 → 秒杀直接下线(开抢前必备演练)+ 页面静态兜底「活动太火爆」;订单库压力超限 → MQ 天然缓冲 + 消费端限速(L10 三件套总动员) |
§5 · 随堂检测
§6 · 检索练习(本课最重要 25 分钟)
盖住全部内容,白板推演:设计「10 万件、500 万人抢」的秒杀系统。要求:画出漏斗并标注每层拒绝率、说明预扣为什么不超卖、说明「Redis 扣了但订单没落库」怎么办。
§7 · 本周行动
行动任务(约 30 分钟)
参加一次真实的秒杀/抢购(12306 候补、演唱会票、限量球鞋都行),全程记录:从点击到结果的每一步(按钮状态、排队提示、失败文案)。用本课的漏斗图反推它的架构,写一份 3 句话的侦探笔记——真实系统的设计决策藏在每一次等待里。
§8 · 延伸资源
- 首选精读:美团技术团队《秒杀系统设计》——国内一线实践[1]
- Stripe 幂等请求——幂等键在支付场景的落地[2]
- 对照阅读:Alex Xu Vol.1「Design a System for a Flash Sale」类章节(各版本章名略有差异)
- 下一课 → Lesson 0013 大案例 III:视频平台
💬 你的白板推演可以贴给我逐项点评。特别欢迎贴你「侦探笔记」——猜错了也没关系,猜的过程就是在练架构嗅觉。