电商秒杀系统
【业务背景】
你作为一个电商创业公司的架构师,负责设计 6.18 大促秒杀系统的设计,你们的业务模式如下:
1. 你们挑选选品各大电商平台上畅销和好评的商品进行销售,每个品类不超过 20 个商品,目前做了 10 个品类;
2. 本次 6.18 秒杀选择了 1000 个充电宝,10 台 iPhone12 作为秒杀商品;
3. 正常的日活大约 100 万用户;
4. 老板要求万无一失。
【技术背景】
1. 技术团队以 Java 为主,已经落地了微服务架构;
2. 主要渠道是自有的 App(包括 iOS 和 Android)和微信小程序,为了促进用户转化为 App 用户,只有下载 App 才能参加秒杀活动;
3. 目前只有单机房。
【约束与限制】
1000 个充电宝,10 个 iphone12,绝对不能超卖
前端使用 android、ios、微信小程序
后端使用 java 实现
6 月 18 日之前完成
【复杂度分析】
秒杀场景的特点为,大量用户在同一时间抢购商品,造成瞬时流量激增,抢购人数远大于库存数量。
电商秒杀主要业务场景有:【浏览商品】,【下单】,【付款】
因为 6.18 秒杀活动都会预热宣传,用户会在宣传期间把自己感兴趣的商品加入购物车,或者等待秒杀开始直接抢购。所以假设 6.18 当天【浏览商品】发生在白天 8 小时之内,因为日活用户有 100 万,假设 6.18 当天有 150 万用户,每人浏览 10 个感兴趣的商品,那么大约会发生 150*10=1500 万次浏览,平均到 8 小时,那么浏览的并发数:1500*10000/(8*60*60)= 520
假设有 1/50 的人会在秒杀开始的时候参与抢购(抢购依赖登录信息与库存信息),抢购成功后可以付款,那么秒杀时刻抢购的并发数大概为:150*10000/50=3 万
假设付款发生在秒杀开始的半个小时内,那么每秒付款的并发数为:150*10000/20/(30*60)=41
5.【浏览商品】典型的读业务,使用 redis 缓存减轻数据库的压力,主要商品有 10 个品类,每个品类最多不超过 20 个商品,大概商品有 20*10=300 个。每个商品详情占用 4KB。秒杀期间热门商品大约占用 1M 内存。
6.【下单】的并发峰值为 3 万,单台 Nginx 可以支撑 5-10 万并发,考虑到老板要求万无一失,所以设计 2 台 Nginx 组成集群比较合理。网关使用 Spring cloud gateway,单台 Spring cloud gateway 可以支持 3K-5K 左右的并发,考虑到冗余设计 10 台 Spring cloud gateway 集群即可。因为【下单】依赖登录信息,所以在 Spring cloud gateway 阶段可以做鉴权同时采用桶算法限流(桶大小可以设置为秒杀商品的库存量大小),登录信息放在 redis 中,同时桶大小也设置在 redis 集群中,单台 redis 并发量大概在 1 万到几万左右,要满足 3 万并发,设计 3 主 3 从的 cluster 集群即可。通过鉴权与限流的流量进入消息队列等待消费。其他流量直接返回。同时,因为只有在 Android iOS 端可以参与秒杀,可以在 gateway 通过设备类型过滤掉小程序过来的请求。
7.假设秒杀商品库存有 3000,经过桶算法限流之后进入消息队列的消息最多只有 3000 个。单台下单服务每秒可以处理 300 个并发,那么 5 台下单服务器可以在 2 个周期内处理完所有的消息。数据库写链接需要 1500 左右,高配单机 MySQL 可以满足,考虑到高可用和性能冗余采用主从模式。
【架构设计】
业务架构图
系统架构图
【设计规范】
1.秒杀开始,前端携带用户 token 信息,设备类型信息,抢购商品 SKU 的 id,数量,经过 Nginx。Nginx 路由到 gateway。
2.gateway 根据设备类型判断是不是可以参与抢购,如果不可以抢购直接返回,提示不可能抢购。如果可以抢购则根据 token 从 redis 中判断登录状态。成功则进入桶限流,桶容量设置为商品的库存量。之后发送到消息队列。同时返回前端排队号。
3.下单微服务消费消息队列信息的时候需要同步调用库存微服务。
4.客户端携带排队号轮询请求订单结果,订单微服务根据排队号,返回订单创建状态(成功,失败,创建中)
5.客户端收到订单创建成功之后,然后调用支付微服务去付款。
版权声明: 本文为 InfoQ 作者【张逃逃】的原创文章。
原文链接:【http://xie.infoq.cn/article/c732f14c5ed2538b86480fd39】。文章转载请联系作者。
评论