之前的文章中我们已经演练了缓存的三种“招式”:用读缓存化解数据库查询压力,靠写缓存扛住流量洪峰,再通过消息队列从容同步数据。这套组合拳——先缓冲、再异步、平稳落库——正是接下来面对真刀真枪的秒杀场景时,我们要继续运用的核心战术。
想象这样一个场面:某天,公司决定拿出100件“骨折价”商品,在10月10日晚上10点10分准时开抢。而这时候,平台已经坐拥几千万用户,哪怕只吸引来几十万想捡便宜的,也意味着 —— 开抢那一两秒,流量会像演唱会放票般瞬间冲顶,之后秒光,只剩“已售罄”的页面迎接后来者。
更“刺激”的是,领导发话:这是个临时活动,服务器不能大动,架构别大改,要求我们“精打细算”地接住这股洪流,别让系统被冲垮。
所以问题来了:如何用最小代价,设计一套秒杀架构?
核心原则其实就这四条,咱们得牢牢守住:
货不能多卖——说好100件就100件;订单不能丢——抢成功的必须算数;系统不能挂——服务器和数据库得稳住;尽量防住机器人——把货留给真人用户。那具体怎么实现?咱们接下来就聊聊整体设计思路。
秒杀架构的本质,就像一个精心设计的“流量漏斗”——它的核心策略是层层设卡,逐级过滤,让越多的请求在上游就被消化或拦截,尽量不让压力渗透到系统底层。
如下图从架构分层的视角看,我们的目标很明确:把请求尽可能拦在上游,别放它往下游冲。系统越靠下游,往往越脆弱、越昂贵,保护数据库和核心服务是重中之重。

那具体怎么拦?不能光靠想象。因为秒杀本身是一连串用户操作(浏览、点击、下单、支付…),所以必须结合完整的业务流程来设计拦截点。每一个用户动作,都是一个可能设防的关卡。下图更直观地展现这个“何处设卡、如何引导”的过程,

接下来就按照秒杀系统的业务流程,来一步步讲解如何将请求拦截在系统上游。
踩过坑才懂,设计秒杀时就算算力绰绰有余,也千万别忽略一个隐形杀手——带宽。我们曾有一个活动,上线后监控一切正常,唯独出口带宽被瞬间占满,结果页面卡成“PPT”,用户体验一落千丈。
吃一堑长一智,从那之后我们学乖了:所有静态资源一律走 CDN,PC 网站也必须做前后端分离。简单来说,CDN 就是把你的图片、样式等文件缓存到全国各地的节点服务器上,用户访问时,由 CDN 智能调度到最近的节点返回资源,又快又省自家服务器的流量和带宽。
这样一来,静态请求的压力基本被挡在系统之外。那么动态请求怎么处理?这里有三种常见思路:
动态数据静态化总结一下原则:
用户浏览类行为,尽量在 CDN、静态服务或负载均衡层完成拦截;实在不行,也必须在缓存层解决,绝不轻易放行到下游数据库。
好,我们直击秒杀最核心的战场——下单与提交。这里的设计,直接决定系统是平稳着陆还是瞬间崩塌。
为了防止“黄牛”或爬虫直接刷爆下单页,我们设下两道防线:
动态URL,绝不提前暴露页面展示可以用CDN扛,但提交订单涉及复杂逻辑与数据一致性,是整套架构的“心脏”。原则是:在请求抵达数据库前,层层设卡,能拦则拦。
目标:用最小代价,在系统最外围拦截掉95%以上的无效或恶意流量。主要三板斧:
用户限频:比如同一用户每5秒只能提交一次。IP限频:防止机器人集群攻击,但需谨慎避免误伤真实用户(例如同一公司出口IP)。总量限流:采用漏桶/令牌桶等算法,严格控制每秒进入后台的请求数量。前两种限制比较简单,在nginx上就能快速完成配置,第3种限流方式也不复杂,相关的原理在后面的
能到达这里的请求已是“幸运儿”,我们的目标转为:保证不超卖、不丢单。
库存决胜在缓存系统虽性能下降,但功能依然可用,保障了基本业务。
总结一下:秒杀提交的设计,是外围狠心限流与内部精心守护的结合。核心思想是:利用缓存扛住并发读写,通过异步化解耦压力,最终以可控的流量与数据库平稳交互。只要守住不超卖、不丢单的底线,这场战役就赢了九成。
来到付款环节,请求的洪峰早已在之前层层关卡被充分过滤。此时的重点不再是拦截,而是稳妥地完成交易闭环。
核心就两件事:
确保最终一致性:支付状态、库存、订单数据必须准确同步。(数据一致性具体如何实现,我们留到后续章节深入探讨。)处理好订单取消:若发生超时未支付等业务取消逻辑,务必记得将释放的库存,同时回补至数据库和 Redis。这一步是防止资源被“锁死”的关键,相当于把回收的“弹药”重新填回弹舱。至此,秒杀流程从流量过滤到交易完结,形成一个完整且有韧性的闭环。

要构建真正扛得住秒杀的“铁桶阵”,高可用设计必须贯穿每一道防线。如图上所示,从上到下,每一层都不能是单点。简单来说,你需要:
前置防线集群化:静态资源服务器、网关、后台服务,统统通过负载均衡来部署,让流量“雨露均沾”,任何一台实例挂掉都无缝切换。核心存储分布式化:缓存(Redis)和数据库(DB),必须采用集群模式。数据分片、主从备份、故障自动切换(Failover),一个都不能少,这是系统不垮的基石。别忘了“幕后英雄”MQ:虽然前面的分层设计里它没直接出场,但服务间异步通知、流量削峰都离不开它。消息队列本身也要高可用配置——主从、分片、故障转移机制都得安排上,确保消息不丢、服务不中断。层层设防,环环相扣,才是高可用的精髓。
好了,关于秒杀架构的核心要点,我们已从头到尾梳理了一遍。由于很多策略在前面的“缓存实战”中已有铺垫,本章更像一次聚焦的综合应用。
为了方便你后续设计与自查,我将关键注意事项整理为一份 《秒杀系统设计Checklist》 ,供你参考:
| 流程 | 事 项 |
|---|---|
| 浏览页面 | 静态资源放CDN |
| 浏览页面 | 秒杀期间的一些动态数据请求放入静态页面 |
| 浏览页面 | 秒杀开始的时间获取依赖服务端 |
| 浏览页面 | 秒杀结束的标识放在各个地方 |
| 下单页面 | 下单URL动态后台获取 |
| 下单页面 | 购买按钮点击后置灰(Disable) 网关从3个方面过滤请求 |
| 下单页面 | 1)用户访问频率 2)IP访问频率 3)整体流量控制 |
| 下单页面 | 库存放在Redis 中,在每次下单操作中判断其是否为0,以防止超卖 |
| 下单页面 | 订单先入缓存再批量落库 |
| 付款页面 | 订单取消时记得将商品量加回数据库和Redis 中的库存 |
| 服务器架构 | 静态资源服务器负载均衡 |
| 服务器架构 | 网关负载均衡 |
| 服务器架构 | 后台服务器负载均衡 |
| 服务器架构 | Redis 集群 |
| 服务器架构 | MQ集群 |
| 服务器架构 | 数据库集群 |
此外,还有三个重要话题我们将在后续章节展开:
服务雪崩防护——万一某个服务挂掉,如何避免连锁反应?(后续讲熔断的时候详细讲解)网关限流实战——具体如何配置与实现?支付数据一致性——怎样确保交易闭环严谨可靠?这三点每一点都需要细致考虑,将在后续文章中详细讲解。
这次架构上线后,我们通过多方监控与数据核对,验证了库存与订单完全匹配,系统运行平稳。这与此前一段“血泪史”形成鲜明对比:早期我们曾设计“保证前100名下单成功”的方案,不做限流,结果后台压力巨大且体验不公——毕竟网速和手速并非公平竞技,普通用户很难拼过“专业选手”。如今通用做法是在网关层做科学限流,让系统在可控压力下随机公平处理请求。有些方案在前端JS随机丢弃请求,虽也算“限流”,但属于不可靠的“小聪明”,应尽量避免。
秒杀场景至此告一段落。接下来,我们将进入下一部分:基于常见组件的微服务场景实战,从最简单的服务治理开始,由浅入深,一步步拆解微服务的核心知识与实践。