设计电商秒杀系统
【业务背景】
你作为一个电商创业公司的架构师,负责设计 6.18 大促秒杀系统的设计,你们的业务模式如下:
1. 你们挑选选品各大电商平台上畅销和好评的商品进行销售,每个品类不超过 20 个商品,目前做了 10 个品类;
2. 本次 6.18 秒杀选择了 1000 个充电宝,10 台 iPhone 12 作为秒杀商品;
3. 正常的日活大约 100 万用户;
4. 老板要求万无一失。
【技术背景】
技术团队以 Java 为主,已经落地了微服务架构;
主要渠道是自有的 App(包括 iOS 和 Android)和微信小程序,为了促进用户转化为 App 用户,只有下载 App 才能参加秒杀活动;
目前只有单机房。
【业务基本场景】
查看商品->秒杀->查看订单
【秒杀场景特点】
1、定时开始,秒杀时大量用户会在同一时间,抢购同一商品,网站瞬时流量激增。
2、库存有限,秒杀下单数量远远大于库存数量,只有少部分用户能够秒杀成功。
3、操作可靠,秒杀业务流程比较简单,一般就是下订单减库存。库存就是用户争夺的“资源”,实际被消费的“资源”不能超过计划要售出的“资源”,也就是不能被“超卖”。
4、安全,要防止脚本执行。
5、系统可靠性,秒杀系统不能影响其他业务系统。
【针对特点需要考虑的问题】
1、网站瞬时流量激增,会导致服务不可用,需要考虑负载均衡、限流、过滤、缓存等技术已达到“削峰”的目的。
2、库存有限,即说明多数请求是无效的,需要考虑过滤、缓存,避免无效 IO。
3、操作可靠,秒杀业务流程比较简单,即不需要事务控制,可以考虑缓存和分布式锁来减少 IO。
【100 万用户存储性能估算】
【用户】
300 万,注册用户,100 万日活用户
【商品】
每天 20*10=200 个商品信息
【订单】
假设每天 200 个商品,每个商品 1000 份,订单=200*1000=20 万
-----------------------------------------------------------------------------------------------------------
【100 万用户计算性能估算】
【注册用户】
可以忽略
【用户登录】
日活 100 万用户,假设登录时间集中在早晚 2 小时,登录 TPS 均值:100 万 / (2*3600)= 138。
【商品查看】
日活 100 万用户,10 个品类,每个品类不超过 20 个商品 20 个商品,每个商品有 60%人感兴趣,会去查看,时间多半集中在活动 1 小时以内 QPS=20*10*100 万*60%/3600≈33 万/s
【商品秒杀】
日活 100 万用户,假设每个商品有 60%人参与秒杀,秒杀集中在 30 秒内,秒杀 TPS=100 万*60%/30=2 万
【订单查看】
假设订单为 20 万,查看集中在 1 小时内,QPS=20 万/3600=6
【分析】
1、100 万的日活 nginx 已经不够用,需要上 LVS,所以使用 DNS+LVS+Getway 三级负载均衡
2、由于技术团队以 Java 为主,在网关集群使用 spring cloud getway 做负载均衡,同时也可以实现限流
3、注册中心采用 spring eruka
在设计之初,我们会为秒杀的商品生成专门的商品页面和订单页面。这些页面以静态的 HTML 为主,包括的动态信息尽量少。
1、在 APP 端,需要缓存商品信息、订单信息(静态 HTML)
2、在 APP 端,缓存动态信息 JS,用来防止作弊
3、在 CDN 缓存静态 HTML,(包括图片)
4、在 web 容器,缓存静态资源(图片、js、css 等)
5、redis Cluster 需要缓存库存和已经处理的订单以减少数据库 IO。
为了防止超卖,需要使用到分布式锁,
如果锁长期没有释放,需要考虑锁的过期时间,需要设置两个超时时间:
1、资源本身的超时时间,一旦资源被使用一段时间还没有被释放,Redis 会自动释放掉该资源给其他服务使用。
2、服务获取资源的超时时间,一旦一个服务获取资源一段时间后,不管该服务是否处理完这个资源,都需要释放该资源给其他服务使用。
----------------------------------------------------------------------------------------------------------
通过微服务拆分将登陆、注册、商品查看、秒杀等功能进行隔离,同时也方便了后续服务扩展。
因为目前只有一个机房,无法实现异地多活,所以在计算高可用上,采用了多实例的方案,每个微服务部署 3 个实例,于此同时,秒杀 TPS 高,为了防止服务被压垮,建立排队机制,将同步请求改为异步请求。
为了应对秒杀这种特殊场景,需要“削峰”,于是设计秒杀流程,将同步请求变为异步请求,从而减轻服务器压力
评论