左手隔离,右手分层!秒杀高并发从0到1
YLY • 发表于2020-03-13 18:17:54 • 19897次阅读
// 隔离的设计思路 //
秒杀活动是有计划的,并且在短时间内会爆发大量的请求。为了不影响日常业务系统的正常运行,我们需要把它和现有的系统做隔离。在设计秒杀系统的时候可以从以下几个方面来思考隔离的问题。业务隔离
在活动开始之前,最好设计一个“热场”。“热场”的形式多种多样,例如:分享活动领优惠卷,领秒杀名额等等。“热场”的形式不重要,重要的是通过它获取一些准备信息。例如:参与的用户数,他们的地域分布,他们感兴趣的商品。别小看这些数据,通过这些数据可以预估出秒杀当天的流量,并发数等信息。而且可以作为压力测试数据来源的一部分,协助测试系统的可用性。
应用隔离
应用的部署多采用分布式或者微服务的架构,通过容器和服务编排的方式部署方式。建议分配给秒杀系统专门的系统资源,来应对高并发。我们可以将原来日常系统中的服务在秒杀系统中复用,也可以为秒杀系统设计专门的服务。
流量隔离
秒杀系统会在短时间内迎来巨大流量。如果此时因为秒杀系统的流量增加,导致日常系统的流量瓶颈是得不偿失的。所以这里需要对流量进行隔离,如果共用负载均衡需要设置秒杀系统使用的流量上限。根据秒杀系统特有的请求头判断流入的请求是来自秒杀请求还是日常系统请求。同时也可以根据用户ID,请求IP、请求的地域来做隔离。
数据隔离
秒杀活动持续时间短,瞬时数据量大。为了不影响现有数据库的正常业务,可以建立新的库或者表来处理。在秒杀结束以后,需要把这部分数据同步到主业务系统中,或者查询表中。如果数据量特别巨大,到千万级别甚至上亿,建议使用分表或者分库。// 分层的设计思路 //
这里我们通过架构分层的方式,逐层讲解如何解决秒杀系统的问题。总结为四横三纵。客户端页面设计需要ESI和CSI方法论作为支撑。前端秒杀页面使用专门的页面,这些页面包括静态的HTML和动态的JS,以及如何使用HTTP和CDN缓存减少对应用服务器的访问。
即使我们扩展再多的应用,使用再多的应用服务器,部署再多的负载均衡器,都会遇到支撑不住海量请求的时候。所以,在这一层我们要考虑的是如何做好流量扩展和流量限制。同时在业务层面可以根据IP,用户名,商品ID对流入秒杀系统的请求进行筛选和控制。并且能够对恶意请求大胆说“不”。并且包括负载均衡算法,限流算法,Nginx实现限流的最佳实践以及OpenResty实现代理层缓存的最佳实践。
瞬时的海量请求好比请求的“高峰”,我们架构系统的目的就是“削峰”。需要使用服务集群和水平扩展,让“高峰”请求分流到不同的服务器进行处理。同时,还会利用缓存和队列技术减轻应用处理的压力,通过异步请求的方式做到最终一致性。由于是多线程操作,而且商品的额度有限,为了解决超卖的问题,需要考虑进程锁的问题。同时也会可以使用进程内的缓存保存一些热点数据,针对分布式缓存提供算法和最佳实践。在遇到服务挂掉的情况,需要有检测和熔断机制。
秒杀活动持续时间短,瞬时数据量大。为了不影响现有数据库的正常业务,可以建立新的库或者表来处理。在秒杀结束以后,需要把这部分数据同步到主业务系统中,或者查询表中。如果数据量特别巨大,到千万级别甚至上亿,建议使用分表或者分库。同时做到读写分离,利用分布式的选举机制保证服务器的高可用。
当系统上线之前我们需要未雨绸缪,针对即将出现的高并发场景进行演练。根据QPS、TPS、BPS对系统设定运行指标,通过压力测试的方式论和测试工具,探查系统的承载底线。
系统上线运行以后,需要时刻监控系统的情况并且作出响应的反映。我们会针对监控系统的功能、分类、分层进行详细介绍。而且会针对Zabbix和ELK的最佳实践,让理论结合实践。
如果说服务一定会遇到问题,那么服务降级就是让问题造成的影响最小化。针对服务不可用的情况设置开关,并且通过ZooKeeper实现开关功能。
把上面7个方面的描述总结为四横三纵。按照用户请求从外到内,从上到下的方向分别是:客户端、代理层、应用层、数据层。压力测试、监控系统、服务降级作为高可用的保障贯穿四层之中形成三纵。(文章来源:51CTO)