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

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 分钟)
		库存超卖
			对普通的商品下单数量超过库存数量的情况,可以通过补货来解决;
			但是有些卖家完全不允许库存为负数的情况,那只能在买家付款时提示库存不足
		库存优化
			在缓存减库存
			数据库并发锁问题
				热点数据隔离
				应用层做排队
				数据库层做排队
	限流降级

猜你喜欢

转载自blog.csdn.net/micklongen/article/details/89763173
今日推荐