Skip to content

在线票务 / 抢票 架构模板

代表产品 / 原型:Ticketmaster、SeatGeek、大麦、12306,以及各类「秒杀」 一句话定位:在开售瞬间海量用户争抢有限的座位 / 库存时,保证不超卖、相对公平、系统不被冲垮。


1. 一句话定位

抢票系统 = 「极端瞬时并发」撞上「有限稀缺资源」的正面战场

百万人在同一秒抢几万张票。它是 电商秒杀 的极致版,还多了一个维度:票常常是「具体的座位」(3 排 12 号只有一个)。它的全部设计,都在同时满足三件几乎冲突的事:绝不超卖、尽量公平、系统别崩。

2. 业务本质:它在解决什么问题

它把极度有限的资源(票 / 座位),在极度集中的时间(开售那一刻),卖给极度海量的人

这件事的特殊性在于「开售即洪峰」:平时没流量,开售瞬间流量涨几千倍,几分钟后又归于平静。为这种尖刺做架构,和为「平稳增长」做架构,思路完全不同。

三条铁律,排好优先级:不超卖(底线)> 不崩(前提)> 公平(体验)。 卖出一张不存在的票,是事故;系统崩了,谁也抢不到;不公平,口碑崩塌。

3. 核心需求与约束

功能性需求:

  • [ ] 放票 / 库存管理(可能精确到座位)
  • [ ] 抢票:扣减库存 / 锁定座位
  • [ ] 锁座(下单未支付时,先占住)+ 超时释放
  • [ ] 下单、支付、出票
  • [ ] 排队、限购、防刷

非功能性需求 / 质量属性:

质量属性目标为什么对这类系统重要
不超卖绝对卖出不存在的票是重大事故
峰值承载抗住开售瞬间洪峰平时低、开售瞬间爆,典型尖刺
公平先到先得 / 防机器人被黄牛脚本扫光,口碑崩
库存实时余票 / 座位状态准用户要看到「还剩几张」

关键约束(不可逾越的边界):

  • 🔴 库存有限且精确:每个座位唯一,不能卖两次。
  • 🔴 并发极端且瞬时:开售一瞬的写竞争集中在极少数「热门库存」上。
  • 🔴 存在「锁定中」中间态:用户下单还没付,票既不能卖给别人、又不能永久占着。
  • 🔪 黄牛 / 脚本:专业团伙用机器抢,公平性面临真实对抗。

4. 架构全景图

   开售瞬间:百万用户涌入
   ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
┌──────────────────────────────────────────────┐
│  虚拟等候室 / 排队(把洪峰挡在核心系统【外】)     │
│  • 所有人先进等候室,拿一个排队号                 │
│  • 按【系统能承受的速率】分批放行进入抢票          │
│  • 防刷:验证、限流、风控在这一层先筛一遍          │
└───────────────────────┬──────────────────────┘
                        ▼ 放行令牌(细水长流,而非洪峰漫灌)
┌──────────────────────────────────────────────┐
│  抢票 / 库存服务                                 │
│  • 库存【原子扣减】(热点库存放内存,绝不超卖)     │
│  • 锁定座位(临时占位)                           │
└───────────────────────┬──────────────────────┘
                        ▼ 抢到 → 生成订单(状态=待支付)
┌──────────────────────────────────────────────┐
│  订单状态机 → 支付 → 出票                         │
│  ⏰ 超时未支付 ──▶ 自动释放锁定的票,回到可售       │
└──────────────────────────────────────────────┘

灵魂是最上面那层虚拟等候室:它的作用不是「让大家排队」,而是把洪峰挡在核心系统之外,按系统真实能力把流量「整形」成平稳水流。没有它,核心系统会在开售那一秒直接被冲垮。

5. 组件职责

  • 虚拟等候室 / 排队:开售时所有人先进队列,按系统承载能力分批放行。为什么需要:这是抗洪峰的根本——保护核心系统不被瞬时流量打死(见决策 1)。
  • 抢票 / 库存服务:用原子操作扣减库存,绝不超卖。为什么需要:防超卖是底线,普通的「读 - 改 - 写」在高并发下必然超卖(见决策 2)。
  • 座位锁定:下单时临时占住座位,给用户支付时间。为什么需要:座位有「正在被某人买」的中间态。
  • 超时释放:回收「占着不付」的锁定。为什么需要:否则票被占死,既卖不出也退不回(见决策 3)。
  • 订单状态机:管「待支付 → 已支付 → 出票 / 取消」。为什么需要:出票关乎钱和库存,状态不能乱。
  • 防刷风控:识别机器人 / 黄牛。为什么需要:公平性面临专业对抗。

6. 关键数据流

场景一:开售抢票(从洪峰到出票)

1. 开售,百万人涌入 ──▶ 全部进【虚拟等候室】,拿排队号
2. 系统按「每秒能处理 N 个」的速率,分批放行 ──▶ 进入抢票服务
3. 抢票:对热门场次库存做【原子扣减】
      扣减成功 ──▶ 锁定座位,生成订单(待支付,给 10 分钟)
      库存为 0 ──▶ 返回「已售罄」
4. 用户支付 ──▶ 出票,库存正式售出
5. ⏰ 10 分钟没付 ──▶ 自动释放,这张票回到可售池

场景二:为什么不超卖(原子扣减)

✗ 错误:先查余量(读到 1)→ 两个请求都以为还有 → 都扣 → 卖出 2 张(超卖!)
✓ 正确:用【原子操作】「扣减并返回结果」,只有一个请求能把最后 1 张减成 0,
        另一个原子操作返回「不足」 → 只卖出 1 张

7. 数据模型与存储选择

核心实体:库存 / 座位(状态:可售 / 锁定 / 售出);订单(状态机);排队令牌

数据存储类型为什么
热门场次库存内存级 KV(原子操作)写竞争极热,数据库行锁扛不住瞬时洪峰
座位图 / 状态内存 + 关系型落账实时性要求高,最终要持久化
订单关系型(强一致)关乎钱和出票,要事务
排队令牌内存级 KV高频、易失

教学点:「热点库存」是个超级写热点——一个爆款场次的库存,瞬间被百万请求争抢同一行。把它放在内存级存储里做原子扣减,而不是让数据库的一行去扛,是抗住洪峰的关键。

8. 关键架构决策与权衡 ⭐

决策 1:虚拟等候室削峰(抗洪峰的根本)⭐

  • 不削峰,让所有人直接打核心系统:开售瞬间核心系统被冲垮,谁也抢不到。
  • 虚拟等候室:把人挡在门外排队,按系统能力放行。
  • 取向:大型抢票必上等候室。把洪峰挡在门外,远比在门内拼命加机器有效——这是应对尖刺流量的第一性原理。

决策 2:库存扣减怎么保证不超卖?⭐

  • 数据库「读余量 - 减余量 - 写回」:非原子,高并发下必然超卖。
  • 数据库行锁 / 乐观锁:能防超卖,但热点行在洪峰下会成为瓶颈。
  • 内存级原子扣减(单线程原子操作):又快又不超卖。
  • 取向:并发不大用数据库行锁 / 乐观锁;热门洪峰场次用内存原子扣减,再异步落库。详见第 12 节。

决策 3:锁座的中间态——占而不付怎么办?⭐

  • 不锁:用户选好座、还没付,被别人抢走 → 体验灾难。
  • 锁了不设超时:占着不付,票永远卖不出去。
  • 锁定 + 超时自动释放。
  • 取向:必做「锁定 + 超时释放」。这是「临时持有稀缺资源」的通用模式——和分布式锁、库存预占同理。

决策 4:同步抢资格,异步走流程。

  • 把「抢到资格(扣减库存)」做成同步、极快、原子;把后续「下单、支付」做成异步流程。
  • 取向:核心争抢点越轻越快越好,把重活儿挪到抢到之后再慢慢做。

9. 规模化与瓶颈

  • 第一个瓶颈:开售峰值。 → 破解:虚拟等候室削峰(根本手段)+ 前端静态化 + CDN。
  • 第二个瓶颈:热点库存写竞争。 → 破解:热点库存放内存原子扣减;极热时分段库存(把 1000 张拆成 10 段各 100 张,分散竞争)。
  • 第三个瓶颈:查余票的读放大。 → 破解:多级缓存(余票状态缓存,容忍秒级延迟)。
  • 第四个瓶颈:排队系统自身要扛住所有人。 → 破解:等候室本身要做得极简、可大量水平扩。

10. 安全与合规要点

  • 🔴 防机器人 / 脚本抢票:验证码、设备指纹、风控、实名 + 限购,对抗黄牛——这是公平性的技术防线。
  • 超卖防护:原子扣减是安全问题(超卖 = 卖出不存在的资产)。
  • 防刷接口:开售前的探测、刷余票接口都要限流。
  • 支付安全:见 支付系统模板

11. 常见误区 / 反模式

  • 开售让所有人直接打核心系统 → ✅ 虚拟等候室削峰,把洪峰挡在门外。
  • 用「查余量 - 减余量」非原子扣减 → ✅ 原子操作 / 行锁,否则必超卖。
  • 锁座不设超时 → ✅ 超时自动释放,别让票被占死。
  • 热点库存硬塞普通数据库扛写 → ✅ 热点放内存原子扣减,必要时分段。
  • 不防机器人 → ✅ 风控 + 实名 + 限购,守住公平。

12. 演进路线:MVP → 成长期 → 成熟期(不同阶段怎么设置)

阶段规模量级怎么设置(具体)此时该操心什么
MVP小型活动报名数据库行锁 / 乐观锁扣减库存即可,并发不大不必上重型方案先保证不超卖,别过度设计
成长期中等抢购热点库存放 内存原子扣减、锁座超时释放、限购、基础防刷、异步下单热点写竞争、超卖、占座释放
成熟期大麦 / 12306 级虚拟等候室削峰、分段库存、多级缓存查余票、风控反黄牛、全链路异步化峰值承载、公平对抗、稳定性

13. 可复用要点

  • 💡 「把洪峰挡在门外」比「在门内加机器」更根本。 排队 / 等候室 / 限流,是应对瞬时尖刺流量的第一选择——这和 消息队列削峰 同源。
  • 💡 原子操作是防超卖的命根子:任何「争抢有限资源」的场景(秒杀、抢券、抢座),都要用原子扣减,而非「读 - 改 - 写」。
  • 💡 「占用 + 超时释放」是处理「临时持有稀缺资源」的通用模式:订座、库存预占、分布式锁,都是它。
  • 💡 把超热点数据放内存:让一行数据库去扛百万并发写,是注定的瓶颈;内存级原子操作才扛得住。

🎯 随堂检验

🤔抗住开售瞬间的抢票洪峰,最根本的手段是?
  • A狂加服务器硬扛
  • B虚拟等候室:把洪峰挡在核心系统门外、按能力放行
  • C限制总售票数量

参考原型与延伸阅读

本模板基于以下公开工程资料整理。抢票 / 票务系统的核心难点(虚拟等候室、削峰、座位锁定)在下面几篇里讲得很透。

📖 工程文章 / 方案:


📌 一句话记住抢票系统:它不是「一个卖票的网站」,而是「极端瞬时洪峰争抢稀缺资源的战场」——所有设计都在回答『怎么同时做到不超卖、不崩、还相对公平』:把洪峰挡在门外、用原子操作守住库存、给占座装上超时。