欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

E. 业务场景 --- 秒杀系统

程序员文章站 2022-04-22 08:05:11
...
E. 业务场景 --- 秒杀系统
	概要
		核心问题
			并发读
			并发写
		秒杀的整体架构可以概括为“稳、准、快”几个关键字
			所谓“稳”,就是整个系统架构要满足高可用
			就是“准”,就是秒杀 10 台 iPhone,那就只能成交10 台,多一台少一台都不行。
			最后再看“快”,“快”其实很好理解,它就是说系统的性能要足够高,否则你怎么支撑这么大的流量呢?
	架构设计原则
		数据要尽量少
			首先是指用户请求的数据能少就少
			其次,“数据要尽量少”还要求系统依赖的数据能少就少
		请求数要尽量少
		路径要尽量短
		依赖要尽量少
			系统降级减少依赖,我们可以给系统进行分级,比如 0 级系统、1 级系统、2 级系统、3 级系统
		不要有单点
	样例概述
		第一阶段
			把秒杀系统独立出来单独打造一个系统,这样可以有针对性地做优化
			在系统部署上也独立做一个机器集群,这样秒杀的大流量就不会影响到正常的商品购买集群的机器负载
			将热点数据(如库存数据)单独放到一个缓存系统中,以提高“读性能”
			增加秒杀答题,防止有秒杀器抢单
		第二阶段
			对页面进行彻底的动静分离,使得用户秒杀时不需要刷新整个页面
			在服务端对秒杀商品进行本地缓存,不需要再调用依赖系统的后台服务获取数据,甚至不需要去公共的缓存集群中查询数据,这样不仅可以减少系统调用,而且能够避免压垮公共缓存集群
			增加系统限流保护,防止最坏情况发生
	高性能/高可用
		关注点
			一点是提高单次请求的效率
			一点是减少没必要的请求
		要点
			动静分离也就是所谓“动态”还是“静态”,并不是说数据本身是否动静,而是数据中是否含有和访问者相关的个性化数据。
				静态数据的处理
					你应该把静态数据缓存到离用户最近的地方
						浏览器
						CDN
						服务器的Cache
					静态化改造就是要直接缓存 HTTP 连接Web 代理服务器根据请求 URL,直接取出对应的 HTTP响应头和响应体然后直接返回,这个响应过程简单得连 HTTP 协议都不用重新组装,甚至连 HTTP 请求头也不需要解析。
					让谁来缓存静态数据也很重要
				动态内容改造
					URL 唯一化
					分离浏览者相关的因素浏览者相关的因素包括是否已登录,以及登录身份等,这些相关因素我们可以单独拆分出来,通过动态请求来获取。
					分离时间因素。服务端输出的时间也通过动态请求获取。
					异步化地域因素。详情页面上与地域相关的因素做成异步方式获取,当然你也可以通过动态请求方式获取,只是这里通过异步获取更合适。
					去掉 Cookie
				动态数据的处理
					ESI 方案(或者 SSI):即在 Web 代理服务器上做动态内容请求,并将请求插入到静态页面中,当用户拿到页面时已经是一个完整的页面了。这种方式对服务端性能有些影响,但是用户体验较好。
					CSI 方案。即单独发起一个异步 JavaScript 请求,以向服务端获取动态内容。这种方式服务端性能更佳,但是用户端页面可能会延时,体验稍差。
				架构方案
					单机部署这种方案是将虚拟机改为实体机,以增大 Cache 的容量,并且采用了一致性 Hash 分组的方式来提升命中率。
						优点
							没有网络瓶颈,而且能使用大内存;
							既能提升命中率,又能减少 Gzip 压缩;
							减少 Cache 失效压力,因为采用定时失效方式,例如只缓存 3 秒钟,过期即自动失效;
						缺点
							一定程度上也造成了 CPU 的浪费,因为单个的 Java 进程很难用完整个实体机的 CPU。
							一个实体机上部署了 Java 应用又作为 Cache 来使用,这造成了运维上的高复杂度
					统一Cache:分布式缓存
						优点
							单独一个 Cache 层,可以减少多个应用接入时使用Cache 的成本。这样接入的应用只要维护自己的 Java 系统就好,不需要单独维护 Cache,而只关心如何使用即可。
							统一 Cache 的方案更易于维护,如后面加强监控、配置的自动化,只需要一套解决方案就行,统一起来维护升级也比较方便。
							可以共享内存,最大化利用内存,不同系统之间的内存可以动态切换,从而能够有效应对各种攻击。
						缺点
							Cache 层内部交换网络成为瓶颈;
							缓存服务器的网卡也会是瓶颈;
							机器少风险较大,挂掉一台就会影响很大一部分缓存数据。
					CDN
						问题
							失效问题
							命中率问题
							发布更新问题
						解决方案
							靠近访问量比较集中的地区;
							离主站相对较远;
							节点到主站间的网络比较好,而且稳定;
							节点容量比较大,不会占用其他 CDN 太多的资源;
			热点数据
				什么是热点
					热点操作
						读请求
						写请求
					热点数据
						静态数据热点:能够提前预测的数据例如,我们可以通过卖家报名的方式提前筛选出来,通过报名系统对这些热点商品进行打标。比如我们分析历史成交记录、用户的购物车记录,来发现哪些商品可能更热门、更好卖
						动态数据热点:系统运行过程总产生的热点例如,卖家在抖音上做了广告,然后商品一下就火了,导致它在短时间内被大量购买。
				问题
					首先,热点请求会大量占用服务器处理资源,虽然这个热点可能只占请求总量的亿分之一,然而却可能抢占 90% 的服务器资源,如果这个热点请求还是没有价值的无效请求,那么对系统资源来说完全是浪费
					其次,即使这些热点是有效的请求,我们也要识别出来做针对性的优化,从而用更低的代价来支撑这些热点请求。
				发现热点
					发现静态热点数据
						静态热点数据可以通过商业手段,例如强制让卖家通过报名参加的方式提前把热点商品筛选出来
						还可以通过技术手段提前预测,例如对买家每天访问的商品进行大数据计算,然后统计出 TOP N 的商品,我们可以认为这些 TOP N 的商品就是热点商品。
					发现动态热点数据
						步骤
							构建一个异步的系统,它可以收集交易链路上各个环节中的中间件产品的热点 Key
							建立一个热点上报和可以按照需求订阅的热点服务的下发规范,主要目的是通过交易链路上各个系统(包括详情、购物车、交易、优惠、库存、物流等)访问的时间差,把上游已经发现的热点透传给下游系统,提前做好保护。
							将上游系统收集的热点数据发送到热点服务台,然后下游系统(如交易系统)就会知道哪些商品会被频繁调用,然后做好热点保护
						注意事项
							这个热点服务后台抓取热点数据日志最好采用异步方式,因为“异步”一方面便于保证通用性,另一方面又不影响业务系统和中间件产品的主流程
							热点服务发现和中间件自身的热点保护模块并存,每个中间件和应用还需要保护自己。
							热点发现要做到接近实时(3s 内完成热点数据的发现)
					处理热点数据
						优化:对于热点数据,直接缓存
						限制:可以把热点商品限制在一个请求队列里,防止因某些热点商品占用太多的服务器资源,而使其他请求始终得不到服务器的处理资源
						隔离
							业务隔离
							系统隔离
							数据隔离
			削峰
				我们知道服务器的处理资源是恒定的,你用或者不用它的处理能力都是一样的,所以出现峰值的话,很容易导致忙到处理不过来,闲的时候却又没有什么要处理。但是由于要保证服务质量,我们的很多处理资源只能按照忙的时候来预估,而这会导致资源的一个浪费
				好处
					一是可以让服务端处理变得更加平稳
					二是可以节省服务器的资源成本
				解决思路
					排队
						消息队列
						线程池
						先进先出、先进后出等常用的内存排队算法的实现方式
					答题
						第一个目的是防止部分买家使用秒杀器在参加秒杀时作弊
						第二个目的其实就是延缓请求,起到对请求流量进行削峰的作用,从而让系统能够更好地支持瞬时的流量高峰。
					过滤:在不同的层次尽可能地过滤掉无效请求,让“漏斗”最末端的才是有效请求
						大部分数据和流量在用户浏览器或者 CDN 上获取,这一层可以拦截大部分数据的读取;
						经过第二层(即前台系统)时数据(包括强一致性的数据)尽量得走 Cache,过滤一些无效的请求;
						再到第三层后台系统,主要做数据的二次检验,对系统做好保护和限流,这样数据量和请求就进一步减少;
						最后在数据层完成数据的强一致性校验
	一致性
		减库存的方式
			下单减库存:但是你要知道,有些人下完单可能并不会付款
			付款减库存:有可能出现买家下单后付不了款的情况,因为可能商品已经被其他人买走了
			预扣库存:买家下单后,库存为其保留一定的时间(如 10 分钟)
		库存超卖
			对普通的商品下单数量超过库存数量的情况,可以通过补货来解决;
			但是有些卖家完全不允许库存为负数的情况,那只能在买家付款时提示库存不足
		库存优化
			在缓存减库存
			数据库并发锁问题
				热点数据隔离
				应用层做排队
				数据库层做排队
	限流降级

 

相关标签: 系统架构 秒杀