《极客时间教程 - 秒杀系统》笔记
《极客时间教程 - 秒杀系统》笔记
开篇词丨秒杀系统架构设计都有哪些关键点?
秒杀的整体架构可以概括为“稳、准、快”几个关键字
- 稳-高可用 - 服务需要考虑各种容错场景,保证服务可用
- 准-一致性 - 高并发下的库存数量增减不能出错,避免超卖
- 快-高性能 - 支持高并发的读写
设计秒杀系统时应该注意的 5 个架构原则
架构原则:“4 要 1 不要”
- 数据尽量少:减少传输数据量(降低 CPU/带宽);减少数据库依赖(降低 DB 压力)
- 请求数尽量少:合并 CSS/JS,减少静态资源请求数
- 路径尽量短:减少数据经过的节点数,降低 I/O 传输耗时
- 依赖尽量少:减少完成一次用户请求必须依赖的系统/服务
- 避免单点:
- 应用服务设计为无状态 + 集群部署
- 数据库通过副本 + 故障转移保证可用性
不同场景下的不同架构案例
10w QPS 架构
- 秒杀系统独立部署,针对性优化
- 独立机器集群,与正常购买集群隔离
- 热点数据(库存)单独缓存,提升读性能
- 秒杀答题机制,防止秒杀器抢单

100w QPS 架构
- 彻底动静分离:无需刷新整页,只刷新抢宝按钮,最小化数据传输
- 服务端本地缓存:避免调用后台服务和公共缓存集群,防止压垮公共缓存
- 系统限流保护:防止最坏情况发生

架构之道,在于权衡取舍。极致性能需在通用性、易用性、成本等方面有所牺牲。
如何才能做好动静分离?有哪些方案可选?
何为动静数据
动态 vs 静态:页面输出是否与 URL、浏览者、时间、地域相关,以及是否含 Cookie 等私密数据。即“每个人看到的页面是否相同”。
静态数据缓存策略:
- 缓存到离用户最近的地方:
CDN、Cookie、服务器缓存 - 直接缓存 HTTP 连接:如
Nginx静态缓存 - 选择合适的缓存组件:
Nginx、Apache、Varnish更擅长处理大并发静态文件请求
如何做动静分离的改造
- URL 唯一化:以唯一 URL 作为缓存 Key(如
id=xxx) - 分离浏览者因素:身份、认证信息等通过动态请求获取
- 分离时间因素:服务端时间通过动态请求获取
- 异步化地域因素:与地域相关的内容异步获取
- 去掉 Cookie:在缓存的静态数据中不含 Cookie(如
Varnish的unset req.http.cookie)
动态内容组织方案:
- ESI/SSI 方案:在 Web 代理服务器上做动态内容请求并插入静态页面,用户体验好但服务端性能稍差
- CSI 方案:单独发起异步 JavaScript 请求获取动态内容,服务端性能更佳但页面可能有延时
动静分离的几种架构方案
方案 1:实体机单机部署
将虚拟机改为实体机,增大 Cache 容量,采用一致性 Hash 分组平衡命中率和访问热点。

优点:无网络瓶颈、大内存、提升命中率、减少 Gzip 压缩、定时失效(如 3 秒)降低 Cache 失效压力
缺点:CPU 利用率低、应用与 Cache 混合部署运维复杂度高
方案 2:统一 Cache 层
将单机 Cache 统一分离,形成独立 Cache 集群。

优点:应用无需单独维护 Cache、运维简单、共享内存最大化利用
缺点:Cache 层内部交换网络瓶颈、网卡瓶颈、单机故障影响大
方案 3:CDN
动静分离后,缓存前置到 CDN,离用户更近,访问更快。
CDN 方案的核心问题:
- 失效问题:全国 CDN 节点需在秒级时间内缓存失效
- 命中率问题:Cache 分散导致命中率降低
- 发布更新问题:业务迭代频繁时发布系统需足够简洁高效
CDN 节点选择原则:靠近访问集中地区、离主站较远、网络稳定、容量大、节点数不宜太多。推荐使用 CDN 二级 Cache(数量少、容量大),未命中再回源站。

二八原则:有针对性地处理好系统的“热点数据”
- 静态热点数据:可提前预测(卖家报名、大数据分析历史成交/购物车)
- 动态热点数据:无法预测,运行中临时产生(如抖音广告突然爆火)
发现热点数据
动态热点发现系统:
- 构建异步系统,收集中间件热点 Key(
Nginx、缓存、RPC框架等) - 建立热点上报和订阅下发规范,上游热点透传给下游提前做好保护
- 热点数据发送到热点服务台,下游系统(如交易系统)做热点保护

处理热点数据
三大思路:优化、限制、隔离
秒杀场景下的隔离策略:
- 业务隔离:秒杀做成营销活动,卖家单独报名,提前预热已知热点
- 系统隔离:分组部署,单独域名,请求落到不同集群
- 数据隔离:单独 Cache 集群/数据库放热点数据,避免影响全量数据
流量削峰这事应该怎么做?
三大思路:排队、答题、分层过滤
排队:MQ 削峰解耦
适用于内部上下游系统调用请求不平缓的场景,消息队列起到削峰和缓冲作用。

答题:延缓请求、限制秒杀器
在请求发起端控制请求速度,配合分层拦截减少无效请求对系统资源的消耗。

分层过滤:多级拦截请求
请求依次经过 CDN → 前台读系统 → 后台系统 → 数据库,逐层过滤。

分层校验原则:
- 动态请求的读数据缓存在 Web 端,过滤无效读
- 读数据不做强一致性校验,减少一致性校验瓶颈
- 写数据基于时间合理分片,过滤过期失效请求
- 写请求做限流保护,过滤超出承载能力的请求
- 写数据做强一致性校验,只保留最后有效数据
影响性能的因素有哪些?又该如何提高系统的性能?
- 影响因素:响应时间、线程数
- 瓶颈发现:
CPU、内存、磁盘、带宽;工具:JProfiler、YourKit、jstack、链路追踪 - 优化方向:编码、序列化、压缩、传输方式(
NIO)、并发
秒杀系统“减库存”设计的核心逻辑
三种减库存方式:
| 方式 | 优点 | 缺点 |
|---|---|---|
| 下单减库存 | 不会超卖,逻辑简单,性能好 | 无法应对下单不付款 |
| 付款减库存 | 不会浪费库存 | 高并发下可能超卖 |
| 预扣库存 | 兼顾库存和付款 | 逻辑复杂 |
秒杀场景:推荐下单减库存(“抢到就是赚到”,不付款概率低,逻辑简单性能好)
保证库存不为负数的方案:
- 应用层事务判断:减后库存为负则回滚
- 数据库字段设为无符号整数:库存小于零时 SQL 报错
CASE WHEN判断:
UPDATE item SET inventory = CASE WHEN inventory >= xxx THEN inventory-xxx ELSE inventory END准备 Plan B:如何设计兜底方案

高可用系统建设各阶段:
| 阶段 | 要点 |
|---|---|
| 设计阶段 | 可扩展性、容错性、避免单点、多活部署 |
| 编码阶段 | 代码健壮性、边界识别、异常处理、合理超时 |
| 测试阶段 | 测试用例覆盖度全面 |
| 发布阶段 | 自动化发布、灰度发布、支持回滚 |
| 运行阶段 | 日志、指标、链路监控 |
| 故障发生 | 容错处理、故障恢复、故障演练 |
降级
核心思想:当系统容量达到阈值时,限制/关闭非核心功能,把有限资源保留给核心业务。

限流
当系统容量达到瓶颈时,限制部分流量保护系统,支持人工开关和自动化保护。

拒绝服务
过载保护:系统负载达到阈值(如 CPU ≥ 90% 或 load ≥ 2×CPU核数)时直接拒绝所有请求。
不得已的兆底方案,防止服务器被压垂导致长时间无法服务。负载下降后易恢复,每个系统和环节都应设置此保护。
高可用建设四大体系:
- 预防:单机压测 → 全链路压测
- 管控:运行时降级、限流、兆底保护
- 监控:性能基线、负载报警、及时预警
- 恢复:故障及时止损、快速数据订正工具