架构实战营 - 毕业设计
前言
题目
【业务背景】
你作为一个电商创业公司的架构师,负责设计 6.18 大促秒杀系统的设计,你们的业务模式如下:
1. 你们挑选选品各大电商平台上畅销和好评的商品进行销售,每个品类不超过 20 个商品,目前做了 10 个品类;
2. 本次 6.18 秒杀选择了 1000 个充电宝,10 台 iPhone 12 作为秒杀商品;
3. 正常的日活大约 100 万用户;
4. 老板要求万无一失。
【技术背景】
1. 技术团队以 Java 为主,已经落地了微服务架构;
2. 主要渠道是自有的 App(包括 iOS 和 Android)和微信小程序,为了促进用户转化为 App 用户,只有下载 App 才能参加秒杀活动;
3. 目前只有单机房。
【毕设要求】
1. 设计完整的架构,例如存储、负载均衡、缓存、高可用、可扩展等;
2. 大约 10 页以内的 PPT,每页 PPT 说明一项设计,包括架构设计和设计理由,无需详细解释备选方案。
题目分析
技术分析
作为一个电商初创公司,可用经费有限,F5 什么的就不要想了,也就是 Nginx 或是 LVS 了
估计公司技术人员也不会超过 20 人,要做一个秒杀系统,能投入的人员就算 10 个吧,这也是特别理想的估算了,
还有一条关键信息目前只有单机房,也就是说机房是自己运维的,服务器也是自己使用自己采购的机器。但是秒杀系统有个很大的问题,它瞬时流量很大,但不会一直使用,没准秒杀一次效果不好以后就不用了。原本的业务不能停,而且不太可能就为这一次秒杀活动采购一批服务器,所以服务器的问题比较偏向使用【云服务】,这个当然要找老板确认,只要老板愿意花钱买新服务器以及承受单机房的风险就好。
团队偏向 Java 技术栈,已经落地微服务,我们就认为是 SpringCloud 全家桶了.
秒杀入口是自家的 APP,但由于秒杀只允许 APP 访问,临近秒杀可能 APP 下载可能会飙升,万一把应用商店挤挂了,虽然作为一个初创电商可能性很低,但为了满足万无一失最好还是在官网提供一下 APP 下载的途径,其他入口都增加该途径的链接。
业务分析
题目中所述的 DAU 为约 100 万,日常 QPS 也就 800~900(按照 100 万用户每人每天查看 3 次,每次的查看 5 个商品,80%请求发生在 4 个小时中,即 1000000*3*5*80%/4/3600 约 1000),日常 TPS 可能也就 100。秒杀场景不同于以往,可能引起大量新用户加入,考虑极端条件用户激增 20%,且总用户的 30%参与秒杀(这个数据无法确定),即秒杀参与人数约为 36 万。这个值的可变性还是很高的,需要跟老板和运营确认有没有比较大的拉新活动,看看主要的客户群体有没有什么特别的反馈,如果没有异常,我们按照 40 万来计算。
目前商品数量不好过 200 个,由于商业模式的原因,未来也不会太多
真正参与秒杀的商品只有 1000 个充电宝和 10 台 iPhone,由于参与秒杀的商品实际上是极少的,因此考虑秒杀系统采用过滤+排队双重措施,过滤将并发降低到 1w,之后限流系统保证请求按照顺序稳定执行,异步通知用户
老板要求万无一失,那么高可用,降级还有各种兜底措施都需要保证
由于秒杀业务是典型的瞬时高并发业务,系统的核心设计是限流和排队组件
正式回答
考虑到毕设背景的公司已经有 100 万的日活用户,已经有了较为成熟的系统来支持日常的业务,因此在秒杀系统中能够复用的就不再重复开发,但还是单独部署。
基本业务场景
用户下载 APP
用户登录 APP
用户查看秒杀页面,通过秒杀状态查询接口查看秒杀是否开始,若秒杀开始则返回秒杀的接口地址(以免过早暴露导致被脚本攻击)
用户通过秒杀接口进行抢购,等待秒杀结果
存储架构设计
存储性能估算
由于我们的场景是秒杀,而且由于货物数量极其有限,其实存储基本需要特殊设计,可以直接与原有的服务对接即可。
由于秒杀没有新的用户因此用户数据保持不变。商品和货物数据也基本保持不变。不需要进行性能估算。
存储架构设计
mysql 作为主要存储,主从自动切换+自建机房备份
为了进一步降低秒杀过程中事务冲突,每种商品都单独一个表存储。
我们的 redis 只用作缓存,因此这里暂不涉及。
计算架构设计
计算性能估算
用户下载和登录 APP 是比较分散的,不会对系统产生较大的压力,因此就不详细讨论了,关键在于秒杀状态查询,秒杀抢购的进行。
上面业务分析那节我们已经估算了参与秒杀的人最多不超过 36 万,按照 40 万取整计算。
【秒杀查询】
峰值不超过 40 万。
【秒杀抢购】
峰值不超过 40 万。
核心点:
秒杀状态查询是查询,需要借助负载均衡以及缓存实现。
秒杀抢购是典型的写操作,因此需要进行排队限流。
缓存设计
基本情况:
app 缓存+web 容器缓存+分布式缓存
详情页等图片信息采用 APP 缓存+web 容器缓存的方式
秒杀状态,库存,排队等情况采用 redis 存储,由于秒杀流量极大,redis 采用 redis cluster 方式部署,估计需要 5 个节点
负载均衡设计
为了保证万无一失,dns+lvs+nginx+服务网关的四级负载均衡。
PS:实际上要是限流技术比较成熟可以考虑通过客户端限流的方式将流量降到 10w 以下,那么负载均衡这块就比较简单了,直接不需要 LVS,直接 Nginx 就可以了。但考虑到时初创团队还是 LVS+nginx 比较保险。
限流设计
秒杀限流采取以下三种方式的结合,做到万无一失:
请求端限流:APP 根据设定的参数(结合监控数据,运维平台动态设置阈值和参数),40W->10W
接入端限流:Nginx 根据设定的规则过滤掉部分请求,(结合监控数据,运维平台动态设定过滤比例),10W->1W
排队限流:排队服务基于漏桶算法实现,实际由 redis 的队列来实现排队服务非常合适。一个商品一个队列。
其他架构设计
高可用设计
根据秒杀系统的特性,为了节约硬件成本以及与原有服务隔离,因此秒杀系统暂定采用云服务部署。因此暂时不需要考虑同城高可用问题,同时用户量不太多,暂时不考虑混合云高可用。
此外为了保证万无一失,准备秒杀兜底方案,在发生异常情况时,主库被打挂了,无法瞬间解决的情况下,运维平台直接让 Nginx 转发到自建机房中的兜底服务器,连接备库提供服务,这时 Nginx 转发策略将请求限流到 2000 以下,如下图所示。
可扩展设计
上面已经分析过了,作为初创电商公司,投入的技术人员可能不超过 30 个,后端人员算 15 个,根据三个火枪手原则,拆分的服务不宜超过 5 个。
服务拆分如下所示:
订单服务
商品服务
支付服务
排队服务
运维监控服务
安全设计
抢购 API 的暴露问题,热点用户监测和处理
可运维性以及可观测性
单独开发运维监控服务来保证可运维性。
通过 Prometheus 实现服务的全面监控
通过监控运维系统时刻观察参与秒杀的用户数量,以及秒杀排队情况
日志,通过 ELK 实现日志的聚合和查看,需要详细的业务日志,可以支持人工回滚
总结
由于有专门的毕业总结的文章,我们就不在这里做过多的总结了,果然秒杀还是互联网技术王冠上最璀璨的瑰宝。
版权声明: 本文为 InfoQ 作者【En wei】的原创文章。
原文链接:【http://xie.infoq.cn/article/0baf3196a437035f23d3b7612】。文章转载请联系作者。
评论