秒杀、大促、抢票,这类场景的技术特征一句话概括:平时一百个请求,活动开始十万个请求,而且全挤在同一件商品上。 常规系统设计思路在这里全面失效:数据库扛不住瞬间洪峰,超卖和少卖都算事故,更麻烦的是流量里还混着大量羊毛党和脚本。
核心矛盾是:请求量远远超过实际成交能力,绝大多数请求注定失败,但必须"失败得快、失败得不伤系统"。 业界有三条主流架构路线:层层拦截的前置限流、队列削峰的异步下单、库存前置的原子扣减,实战中通常组合使用,但各有侧重。
原理: 把绝大多数请求挡在系统之外:活动页面全静态化走 CDN,下单接口在网关层限流(令牌桶按秒放人),配合验证码、排队页过滤机器流量。后端只接收"放进来"的小部分流量。
优点:
缺点:
适用场景: 流量峰值可控的中小规模活动(几万 QPS 以内),或者作为大型活动的第一道防线。所有秒杀方案的必修课,区别只在是不是唯一手段。
原理: 下单请求先进消息队列,立即返回"排队中";后端消费者按系统承受能力匀速消费,扣库存、建订单,结果通过轮询或推送通知用户。把瞬时的洪水变成匀速的小溪。
优点:
缺点:
适用场景: 大流量电商大促、热门抢票的标准解法。订单量巨大且用户能接受"稍等片刻看结果"的场景,这是主路。
原理: 库存从数据库前置到 Redis,活动开始时就加载好;扣减用 Lua 脚本保证原子性(查库存、扣库存一步完成),扣完异步同步回数据库落订单。数据库从头到尾不碰热点库存。
优点:
缺点:
适用场景: 对"立即知道结果"要求高的场景:秒杀、抽签、限量发售。通常和队列方案搭配——Redis 负责扣库存那一刻的正确,队列负责后续订单流程的平稳。
场景特征 | 推荐方案 |
|---|---|
峰值几万 QPS 以内、预算有限 | 前置限流 + 静态化 |
订单量大、接受异步结果 | 队列削峰 + 异步下单 |
要求即时反馈、库存强一致 | 库存前置 + 原子扣减 |
真正的大促 | 三者组合:网关限流 → Redis 扣库存 → 队列下单 |
大型活动的标准姿势是三段式:CDN 和网关挡掉九成流量,Redis 原子扣减守住库存正确性,消息队列消化订单创建的洪峰。每一层只干自己最擅长的事。
第一件:全链路压测,别压单点。 只压下单接口的压测都是自欺欺人:登录、风控、库存、支付,链路任何一环打满都是崩。压测要按真实用户行为配比,并且压到崩为止——你得知道系统的天花板在哪。
第二件:降级预案写在代码里,不是文档里。 库存服务挂了怎么降级、队列堆积怎么限流、支付超时怎么兜底,每一种"挂了怎么办"都要有代码级的开关。预案在文档里的系统,事故时等于没有预案。
第三件:防刷要在业务层做。 网关限流挡不住"看起来像真人"的脚本:设备指纹、行为验证码、账号限购、黑名单,风控规则要和活动方案一起设计。秒杀商品被羊毛党包场一次,口碑损失比系统崩了还大。
秒杀系统的本质不是"让所有请求成功",而是"让注定的失败快速且体面,让该成功的少数稳定且正确"。三层方案没有高低之分,差别在于流量规模和用户体验的取舍——但有一点没有取舍:库存正确性是底线,超卖一次,活动的账就算不过来了。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。