当前位置: 首页 > 后端技术 > Java

图-说说“秒杀”

时间:2023-04-01 23:42:15 Java

1。需求分析“秒杀”一词在电商行业频繁出现,比如京东或淘宝平台上的各种“秒杀”活动,最典型的就是“双十一”抢购。“秒杀”是指限时抢购有限数量商品的行为,是商家以“低价低量”商品获取用户的一种营销方式。01.功能需求其实就是整个秒杀的业务场景并不复杂,可以立即查看参与秒杀的商品信息,以及购买和支付的动作,如下图。秒杀业务最大的挑战在于三点:瞬时:持续时间极短,对于热门和竞争激烈的产品,通常只有一秒钟巨大的流量:因为价格低,产品性价比高,正常购买需要高价,会吸引大量用户争夺。数量有限:由于产品价格低廉,性价比高,只有极少数产品参与秒杀。同时,在保证高并发流量接受的前提下,为提升用户体验和事件规则的公平性,防止恶意破坏,特增加如下要求:(1)用户无需刷新“抢夺”页面一直按钮,当秒杀活动开始时,该按钮会自动亮起。(2)在公平、防止恶意破坏的原则下,下单前添加验证码输入或答疑相关链接。(3)库存不能有问题,即不能扣太多也不能太少。(4)整个秒杀活动持续10分钟。02.性能指标预估从秒杀的需求描述可以看出,目前的秒杀活动主要需要预估三个性能指标:存储容量、并发量、网络带宽。1)由于是闪购活动,存储容量非常有限,参与的产品基本都是低价高性价比。所以订单入库基本不用考虑太多。2)并发量为5000万用户平均每人访问2次,并发量约16.7万/秒(5000w2/1060)。预留部分,可以预估每秒25万左右(也可以下载double)。3)网络带宽在带宽方面,需要进行相关优化。数据传输越少越好。假设单次传输0.5KB,根据并发量(25w0.5KB=122MB8bit=977Mb)估算网络带宽约为977Mb。03.非功能性需求非功能性需求是任何系统都必须考虑的,尤其是公司的核心系统。当前秒杀业务系统的非功能性需求主要体现在以下几点:高可用性,在整个秒杀活动期间,能够为用户提供服务。高性能,让每一位用户都能感受到极快的闪现响应,不会出现大量用户高延迟的现象。可扩展性,当流量高于预期时,有平滑扩展策略(部分产品还设计为友好拒绝策略)。2.概要设计基于对秒杀业务本身的认知以及上述秒杀业务需求,秒杀系统的设计需要重点关注以下几点:(1)动静分离:如何保证用户不刷新页面还能继续浏览吗?可以在不延迟闪购活动开始的情况下获取与闪购相关的数据。(2)流量分层,如何有效防控庞大的流量,不至于压垮后台服务,如何避免前端页面卡死。(3)高可用:如何保证后台持续提供服务。(4)存货抵扣:如何有效抵扣存货。01.动静分离动静分离是指静态页面和动态页面(或静态数据和动态数据)的解耦和分离,使用不同的系统来承载相应的流量。这样可以提高整体的服务访问性能和可维护性。产品秒杀页面的静态数据和动态数据分别提供在不同的地方,如下图所示。静态数据是指页面上几乎不发生变化的数据(即不是根据用户的cookie、基本信息、地区、时间等各种属性生成的数据),如CSS、JavaScript中的静态文件。活动页面中的HTML静态文件。图像和其他相关资源文件。其他与用户信息无关的静态数据。可以缓存这种分离的静态数据。缓存之后,提高了这些静态数据的访问效率,系统速度更快。代理服务器可用于缓存静态数据。动态数据是指根据当前用户属性动态生成的数据。在浏览淘宝首页时,每个用户看到的都是不同的商品。不同的建议;在百度搜索中,根据不同的用户输入条件和用户习惯给出不同的结果页面。这里面的数据是动态数据。02.流量分层在“秒杀”业务中,产品的价格非常具有吸引力,因此会吸引很多用户的眼球,但产品数量有限。因此,几千万用户中,只有100人可能得到产品。对于系统来说,90%以上的流量都是无效流量。“秒杀”商家希望有大量用户关注“秒杀”活动,但当用户真正下单时,这些流量都放不下。因此,需要设计一种高效的流量控制方案,有效控制请求流量。,过滤掉不必要的流量。对于瞬时流量高峰,可以采用倒三角逐层控制的方式,分为四层:CDN、反向代理(Nginx)、后端服务、DB。接下来我们看看各个层级是如何控制流量的,如下图所示。03.高可用性为了在“秒杀”活动的整个过程中为用户提供良好的体验,秒杀系统架构不能设计成单节点架构。单节点是所有系统设计的大忌,因为单节点系统意味着系统高度不稳定,可能不可用,给企业带来直接损失。在设计系统时(尤其是像“秒杀”这样需要高并发的系统),需要保证系统的高可用,如下图所示。04.库存扣减对于“秒杀”活动,通常公司不允许商品超卖(即成功下单的数量不能大于商品的库存数量)。一旦超卖,将给公司造成损失。如果被恶意流量利用,损失是巨大的。库存是电商平台重要的经营指标,因此需要在技术上设计合理的库存扣减,不能出现“超卖”现象。库存扣除通常有以下三种方式:库存订单扣除:用户下单后扣除库存。存货付款扣款:用户付款后,存货将被扣款。预扣库存:用户下单后,系统会锁定库存一段时间,锁定时间到期后自动释放锁定库存。05.系统架构设计根据以上讨论,目前的秒杀架构如下图所示。上面的结构比较简单,主要分为以下五层。用户层:客户端的展示部分,主要涉及产品信息和当前“秒杀”活动信息。CDN层:缓存“秒杀”活动的静态资源文件。负载均衡层:拦截请求、分发路由等。服务层:“秒杀”活动具体事务的相关逻辑处理。基础设施层:数据存储、大数据计算、消息推送等相关操作。其部署架构图如下:三、详细设计01.动静分离设计实现动静分离架构可以采用“分而治之”的方式,即将动态数据和静态数据解耦,利用它们各自架构系统承载相应的流量:对于静态数据,建议缩短用户请求路径,因为路径越短,访问速度越快。此外,静态数据应尽可能缓存。对于动态数据,一般需要客户端与服务端交互获取。因此,请求路径较长,访问速度会较慢。下图为动静分离方案。静态数据访问速度快,而动态数据访问速度慢。那么试想一下,是否可以将需要动态获取的数据提前生成,然后利用静态页面加速技术进行访问呢?如果这是可能的,那么动态数据访问的速度就会变得更快。这是可能的,并且需要使用更流行的“页面静态”技术。页面静态技术是指直接缓存HTTP连接,而不仅仅是缓存数据。如下图,代理服务器根据请求的URL直接返回相应的HTTP响应头和响应报文体,过程简单高效。02.流量分层设计流量分层主要体现在对CDN层、反向代理层、后端服务层和数据层流量的控制。1)CDN层的流量控制可以想象为动静分离技术:尽量提前生成尽可能多的数据,然后放入CDN节点缓存中(因为CDN层在条款上离用户比较近)物理架构)。因此,如果大部分流量都在这一层获取数据,那么到达后端的流量就会减少很多,如下图所示。2)反向代理层流量控制在动静分离方案中提到通过“页面静态技术”加速获取动态数据,即预先生成动态数据,然后进行静态处理。因此,基于页面静态加速技术,可以通过后端服务Job,定时提前生成前端所需的静态数据;分发给所有的反向代理服务器,如下图所示。在“秒杀”业务中,活动详情页有倒计时模块,用户可以看到当前“秒杀”活动还剩多少时间开始。这个逻辑简单的功能可以直接使用Nginx实现:使用nginx-lua插件,使用lua脚本获取当前Nginx服务器的时间,计算倒计时。此外,还可以通过Nginx直接访问分布式缓存获取商品库存数据,如下图所示。“秒杀”业务中的商品价格很低,对用户的吸引力很大,因此可能会有人利用“秒杀器”进行不正当竞争,可能会出现竞争对手恶意刷单的情况。如果有这样的情况,那么这个活动就是有风险的。万一库存被恶意流量垄断,普通用户将无法抢购商品。导致后台系统瘫痪。对于这样的恶意请求,最好有一种机制可以提前检测出来,提前封住恶意请求。可以在Nginx层进行控制;还可以在Nginx中配置用户的访问频率(比如每分钟只访问10次);也可以使用Lua脚本编写一些简单的业务逻辑接口,例如直接拦截指定调用接口IP地址或UserAgent的请求。3)后端服务层流控对于服务层的流控,有以下建议:在程序开发方面,代码应该是独立的,不应该与平台上的其他项目相结合。部署时,应用独立部署,分散流量,防止不合适的流量影响主业务。使用独立的域名,或者按照一定的URL规则在反向代理层进行路由。做好系统保护和限流工作,进一步减少不必要的流量。当“到达系统的请求数”明显大于“系统可以处理的最大请求数”时,可以直接拒绝这些多余的请求,并返回“秒杀”活动结束的信息直接退货了例如活动开始时商品库存为100,当前库存只有50,如果“每台服务器处理的请求数”已经超过“商品库存总量(100)”,则可以直接终止冗余请求。4)数据库层流量控制对于请求到数据的流量,写入的流量是实际下单成功的流量,也就是需要扣库存的动作。有以下建议:如果不是临时活动,建议使用独立的数据库作为“秒杀”活动的数据库。配置数据库读写分离。尝试删除行锁。对于数据库行锁的优化,可以通过拆分商品——增加ID来实现,如下图。对于单个“秒杀”活动,这会产生显着效果。从流量分层控制方案可以看出,瞬时流量好像被一个漏斗过滤掉了,数据和请求量要尽可能的逐层过滤掉。这种流量分层控制的核心思想是在不同层级尽可能过滤掉无效请求,到达“倒三角”末端的请求为有效请求。5)高可用在设计系统的时候,我们要做到高可用,避免单节点的一个小技巧:让服务无状态。如果不能做到完全无状态(比如存储系统),可以通过冗余的多个备份节点来避免单节点。03.库存扣减设计因为在“秒杀”场景下,商品一般都有很大的优惠力度,对用户的吸引力很大。因此,在该场景下使用“订单抵扣存货”的方式更为合适。在“秒杀”场景下,大部分用户基本都会抱着“拿到就是赚”的想法去付费,但是如果有竞争对手恶意下单不付款,我们该怎么办呢?上面在流控中提到,可以对请求日志进行实时分析,让风控系统选择恶意用户,然后进行阻断。在“秒杀”场景下,可以通过分级流控对大量“读”请求进行分级控制。但是,仍然会有大量的流量进入真正的订单逻辑。对于这么大的流量,除了上面提到的数据库隔离之外,还需要进一步优化库存,否则数据库读写仍然是系统的瓶颈。接下来我们看一下在高流量“秒杀”场景下,如何优化库存扣量操作。1)使用缓存技术在“秒杀”场景下,如果只是扣除库存数量等简单流程,可以先将库存数量直接放在缓存中,再利用分布式缓存的超高性能(如Redis)来应对这个瞬时流量高峰下的系统挑战。使用缓存存在一定的风险。比如缓存节点出现异常,应该如何计算库存?使用缓存,不仅要考虑分布式缓存的高可用(如何设计可以参考我的新书《高并发系统实践》),还要考虑各种限流容错机制确保分布式缓存对外提供服务。2)如果异步处理技??术是复杂的库存扣减(比如涉及产品信息本身或涉及其他系统),建议使用数据库扣减库存数量,可以采用异步方式处理通过这种高度并发的库存更新。①用户下单时,订单并不会立即生成,而是将所有订单一个一个放入队列。②下单模块根据自身处理速度依次从队列中获取订单,进行“下单扣库存”操作。③订单生成成功后,用户即可进行支付操作。该方式针对“秒杀”场景,本着“先到先得”的原则,确保公平公正。所有用户都可以抢购,然后等待订单处理完毕,最后生成订单(库存不足会导致订单生成失败)。这样的逻辑对用户来说并不是一个糟糕的体验。具体的排队逻辑如下图所示。4、构建千万级流量的“秒杀”系统需要哪些技术?千万级流量“秒杀”系统的基本架构、“秒杀”系统的设计原则、如何实现动静分离方案和流量控制、扣库存方面的内容。这些都是设计高并发“秒杀”系统必须要考虑的。“秒杀”系统的流程并不复杂——只是一个“下单扣库存”的动作,但由于其独特的业务特性,在设计系统时不能马虎。瞬时流量高峰的高并发“秒杀”系统,我们需要什么技术?让我们在下面总结一下。(1)静态数据技术用于处理高并发读请求,主要涉及以下内容:对缓存的各级处理(即多级缓存技术)分布式缓存技术(2)负载均衡反向代理技术LVSNginx(3)异步处理技??术消息队列技术队列系统技术(4)系统架构设计技术系统模块化微服务架构思想(5)系统监控技术日志监控服务监控