You are on page 1of 11

设计⼀个⾼并发、⾼可⽤秒杀系统 - 知乎 2022/1/13 上午10:39

设计⼀个⾼并发、⾼可⽤秒杀系统

如今的互联⽹已经在海量服务领域有了很成熟的理论,因此⾃⼰也很
庆幸,能够从 0 到 1 完整践⾏海量服务。微视春节项⽬中的集卡⽠分
活动,是⼀个典型的秒杀场景,⾃⼰参与其中,分享⼀些⼼得和总
结。

如今的互联⽹已经在海量服务领域有了很成熟的理论,因此⾃⼰也很庆
幸,能够从 0 到 1 完整践⾏海量服务。微视春节项⽬中的集卡⽠分活动,
是⼀个典型的秒杀场景,⾃⼰参与其中,分享⼀些⼼得和总结。

https://zhuanlan.zhihu.com/p/109742840 第1/11⻚
设计⼀个⾼并发、⾼可⽤秒杀系统 - 知乎 2022/1/13 上午10:39

秒杀系统的难点
友好的⽤户体验
⽤户不能接受破窗的体验,例如:系统超时、系统错误的提示,
或者直接 404 ⻚⾯
瞬时⾼并发流量的挑战
⽊桶短板理论,整个系统的瓶颈往往都在 DB,如何设计出⾼并
发、⾼可⽤系统?

如何设计

上图是⼀个典型的互联⽹业务,⽤户完成⼀个写操作,⼀般会通过接⼊层
和逻辑层,这⾥的服务都是⽆状态,可以通过平⾏拓展去解决⾼并发的问

https://zhuanlan.zhihu.com/p/109742840 第2/11⻚
设计⼀个⾼并发、⾼可⽤秒杀系统 - 知乎 2022/1/13 上午10:39

题;到了 db 层,必须要落到介质中,可以是磁盘/ssd/内存,如果出现
key 的冲突,会有⼀些并发控制技术,例如 cas/加锁/串⾏排队等。

直筒型

直筒型业务,指的是⽤户请求 1:1 的洞穿到 db 层,如下图所示。在⽐较简


单的业务中,才会采⽤这个模型。随着业务规模复杂度上来,⼀定会有
db 和逻辑层分离、逻辑层和接⼊层分离。

漏⽃型

漏⽃型业务,指的是,⽤户的请求,从客户端到 db 层,层层递减,递减
的程度视业务⽽定。例如当 10w ⼈去抢 1 个物品时,db 层的请求在个位
数量级,这就是⽐较理想的模型。如下图所示
https://zhuanlan.zhihu.com/p/109742840 第3/11⻚
设计⼀个⾼并发、⾼可⽤秒杀系统 - 知乎 2022/1/13 上午10:39

这个模型,是⾼并发的基础,翻译⼀下就是下⾯这些:

及早发现,及早拒绝
Fast Fail
前端保护后端

如何实现漏⽃型系统

漏⽃型系统需要从产品策略/客户端/接⼊层/逻辑层/DB 层全⽅位⽴体的设
计。

https://zhuanlan.zhihu.com/p/109742840 第4/11⻚
设计⼀个⾼并发、⾼可⽤秒杀系统 - 知乎 2022/1/13 上午10:39

产品策略

轻重逻辑分离,以秒杀为例,将抢到和到账分开;
抢到,是⽐较轻的操作,库存扣成功后,就可以成功了
到账,是⽐较重的操作,需要涉及到到事务操作
⽤户分流,以整点秒杀活动为例,在 1 分钟内,陆续对⽤户放开⼊
⼝,将所有⽤户请求打散在 60s 内,请求就可以降⼀个数量级
⻚⾯简化,在秒杀开始的时候,需要简化⻚⾯展示,该时刻只保留和
秒杀相关的功能。例如,秒杀开始的时候,⻚⾯可以不展示推荐的商
品。

https://zhuanlan.zhihu.com/p/109742840 第5/11⻚
设计⼀个⾼并发、⾼可⽤秒杀系统 - 知乎 2022/1/13 上午10:39

客户端

重试策略⾮常关键,如果⽤户秒杀失败了,频繁重试,会加剧后端的
雪崩。如何重试呢?根据后端返回码的约定,有两种⽅法:
不允许重试错误,此时 ui 和⽂案都需要有⼀个提示。同时不允
许重试
可重试错误,需要策略重试,例如⼆进制退避法。同时⽂案和 ui
需要提示。
ui 和⽂案,秒杀开始前后,⽤户的所有异常都需要有精⼼设计的 ui
和⽂案提示。例如:【当前活动太⽕爆,请稍后再重试】【你的货物
堵在路上,请稍后查看】等
前端随机丢弃请求可以作为降级⽅案,当⽤户流量远远⼤于系统容量
时,⼈⼯下发随机丢弃标记,⽤户本地客户端开始随机丢弃请求。

接⼊层

所有请求需要鉴权,校验合法身份
如果是⻓链接的服务,鉴权粒度可以在 session 级别;如果是短
链接业务,需要应对这种⾼并发流量,例如 cache 等
根据后端系统容量,需要⼀个全局的限流功能,通常有两种做法:
设置好 N 后,动态获取机器部署情况 M,然后下发单机限流值
N/M。要求请求均匀访问,部署机器统⼀。
维护全局 key,以时间戳建 key。有热 key 问题,可以通过增加
更细粒度的 key 或者定时更新 key 的⽅法。
对于单⽤户/单 ip 需要频控,主要是防⿊产和恶意⽤户。如果秒杀是
有条件的,例如需要完成 xxx 任务,解锁资格,对于获得资格的步
骤,可以进⾏安全扫描,识别出⿊产和恶意⽤户。

逻辑层

逻辑层⾸先应该进⼊校验逻辑,例如参数的合法性,是否有资格,如
果失败的⽤户,快速返回,避免请求洞穿到 db。
异步补单,对于已经扣除秒杀资格的⽤户,如果发货失败后,通常的

https://zhuanlan.zhihu.com/p/109742840 第6/11⻚
设计⼀个⾼并发、⾼可⽤秒杀系统 - 知乎 2022/1/13 上午10:39

两种做法是:
事务回滚,回滚本次⾏为,提示⽤户重试。这个代价特别⼤,⽽
且⽤户重试和前⾯的重试策略结合的话,⽤户体验也不⼤流畅。
异步重做,记录本次⽤户的 log,提示⽤户【稍后查看,正在发
货中】,后台在峰值过后,启动异步补单。需要服务⽀持幂等
对于发货的库存,需要处理热 key。通常的做法是,维护多个 key,
每个⽤户固定去某个查询库存。对于⼤量⼈抢红包的场景,可以提前
分配。

存储层

对于业务模型⽽⾔,对于 db 的要求需要保证⼏个原则:

可靠性
主备:主备能互相切换,⼀般要求在同城跨机房
异地容灾:当⼀地异常,数据能恢复,异地能选主
数据需要持久化到磁盘,或者更冷的设备
⼀致性
对于秒杀⽽⾔,需要严格的⼀致性,⼀般要求主备严格的⼀致。

实践⸺微视集卡⽠分系统
微视集卡⽠分项⽬属于微视春节项⽬之⼀。⽤户的体验流程如下:

架构图

https://zhuanlan.zhihu.com/p/109742840 第7/11⻚
设计⼀个⾼并发、⾼可⽤秒杀系统 - 知乎 2022/1/13 上午10:39

客户端主要是微视主 app 和 h5 ⻚⾯,主 app 是⼊⼝,h5 ⻚⾯是集


卡活动⻚⾯和⽠分⻚⾯。
逻辑部分为分:发卡来源、集卡模块、奖品模块,发卡来源主要是任
务模块;集卡模块主要由活动模块和集卡模块组成。⽠分部分主要在
活动控制层。
奖品模块主要是发钱和其他奖品。

⽠分降级预案

为了做好⽠分时刻的⾼并发,对整个系统需要保证两个重要的事情:

全链路梳理,包括调⽤链的合理性和时延设置

https://zhuanlan.zhihu.com/p/109742840 第8/11⻚
设计⼀个⾼并发、⾼可⽤秒杀系统 - 知乎 2022/1/13 上午10:39

降级服务预案分析,提升系统的鲁棒性

如下图所示,是针对⽠分全链路调⽤分析如下图,需要特别说明的⼏点:

时延很重要,需要全链路分析。不但可以提⾼吞吐量,⽽且可以快速
暴露系统的瓶颈。
峰值时刻,补单逻辑需要关闭,避免加剧雪崩。

我们的降级预案⼤概如下:

⼀级预案,⽠分时刻前后 5 分钟⾃动进⼊:
⼊⼝处 1 分钟内陆续放开⼊⼝倒计时,未登录⽤户不弹⼊⼝
主会场排队,以进⼊主会场 100wqps 为例,超过了进⼊排队,
由接⼊层频控控制
拉取资格接⼝排队,拉取资格接⼝ 100wqps,超过了进⼊排
队,由接⼊层频控控制
抢红包排队,抢红包 100wqps,超过了进⼊排队,由接⼊层频
控控制
红包到账排队,如果资格扣除成功,现⾦发放失败,进⼊排队,
24 ⼩时内到账。异步补单
⼊⼝处调⽤后端⾮关键 rpc:ParticipateStatus,⼿动关闭
异步补单逻辑关闭。

https://zhuanlan.zhihu.com/p/109742840 第9/11⻚
设计⼀个⾼并发、⾼可⽤秒杀系统 - 知乎 2022/1/13 上午10:39

⼆级预案,后端随机丢请求,接⼊层频控失效或者下游服务过载,⼿
动开启进⼊
三级预案,前端随机丢请求,后端服务过载或者宕机进⼊。⼿动开启

综上,整个⽠分时刻体验如下所示:

回顾下漏⽃模型,总结下整个实践:

https://zhuanlan.zhihu.com/p/109742840 第10/11⻚
设计⼀个⾼并发、⾼可⽤秒杀系统 - 知乎 2022/1/13 上午10:39

作者:vincentsu,腾讯 PCG 后台开发⼯程师

更多⼲货,尽在腾讯技术

https://zhuanlan.zhihu.com/p/109742840 第11/11⻚

You might also like