前言
Hi 你好,我是东东拿铁,95后奶爸程序员。
上文为大家介绍了秒杀系统的动静分离,如果你想了解,可以直接戳链接查看
了解完动静分离,我们已经对我们的系统数据做出了最基本的拆分,通过缓存、CDN的方式,可以大大减少我们系统的负载。
但是,"秒杀"对资源的消耗是瞬时的,秒杀请求会高度集中在某一个时间点。从业务上来说,我们自然是希望参与的人越多越好。但商品的库存一定是定量的,从技术角度来说,我们希望真正秒杀的请求,是越少越好,否则对于秒杀的后续热点操作来说,对服务器的压力依旧很大。
开始阅读前,我们不妨先问自己几个问题
1、大家都能提出削峰、解耦,可具体要应用在哪个阶段,保护的是谁?
2、如果可以想到MQ,那MQ处理数据,用户的请求如何处理?
如果你能够有着很清晰的答案,那么大佬请收下我的膝盖,文中错误与不足请不吝指教。
如果你还有着些许疑问,希望本文能够给你带来帮助。
本文将讲述一下,如何做到流量削峰。
为什么要削峰
既然请求是瞬时的,那就意味着,绝大部分时间,我们的系统压力都在低区间运行,没有什么请求要处理。对于秒杀这个场景,我们会提前对于活动的流量进行预估,但用充足的服务器去做准备,会造成很大的资源浪费。
举个例子:比如我们的秒杀商品库存有500,单机器支持下单的TPS是100,如果这500个库存的下单流量在1s内过来,我们需要部署5台机器,来支持这部分瞬时流量。那假设我们库存有5000,那我们就需要50台机器才能支撑我们的服务。
削峰就是针对这个场景而生,让服务端能够处理的更加平稳,减少尖刺的发生,从而用合适的机器来去部署,减少资源浪费。
架构设计
排队
说起流量削峰,大家脑海中第一个蹦出的一定是用消息队列来缓冲瞬时流量,把同步的下单相关操作,转变为异步的间接推送。消息队列一端接收洪峰流量,另一端平滑消费即可。
MQ所保护的下游系统,大家可以自己针对架构设计去进行调整,比如服务A是我们的秒杀系统,只保留了最简单的秒杀是否成功的逻辑。但是下游的商品服务、支付服务并不能做到和秒杀服务一样的高性能,那么服务B就可以是你的商品服务。
这样就能最大程度上保证我们的商品服务,在什么样的流量场景下,都不会影响到最基础的下单操作,避免因为秒杀流量太大,导致普通商品的下单失败。
文章开头也提到了,相信大家会有一个疑问
使用MQ来进行解耦,用户的结果如何返回呢?
常见的有两种方案:
一、页面采用轮询的方式去服务端查询结果,比如1s一次,支付相关的很多业务都会采用这种形式,比如银行转账的时候,页面会有一个倒计时,成功了页面会跳转。当然这种方案,会增加一些服务端的请求。
二、服务端主动push,不过需要服务端与客户端保持连接,会增加很多服务端连接数
答题
不知道你是否还记得,之前的秒杀相关功能,无论是淘宝,还是12306,之前在秒杀时,只需要不断的点击按钮就可以了,近几年来逐渐增加了答题、图片验证功能,这是为什么呢?
主要是为了增加购买的复杂度,解决了下面的两个问题。
第一个目的是防止秒杀器、抢票器等自动化软件,避免通过大量的接口请求,影响到正常用户的秒杀操作。
第二个目的时延缓请求,间接对流量形成削峰的作用。用户在真正秒杀时,答题的操作会将下单的时间延缓2~5s。这样的话就把峰值请求打散,大大的减轻服务器压力。
分层过滤
分层过滤,是对用户的无效请求进行过滤,就像流量漏斗的形式,尽量保证服务器处理的请求,都是有效请求。
举例:
比如CDN,能够拦截大量的读数据请求,CDN对页面数据进行了缓存。
当流量请求到服务器,则把关键数据,尽量走Cache,比如商品详情,图片等。
当真正请求到后台系统,则要做好数据的二次校验,如加密,时间戳有效期,校验活动是否结束,或者库存是否充足,商品状态是否正常等,并在这个阶段,充分做好限流,进一步过滤无效请求。
最后处理好下单逻辑即可。
总结一下
本篇文章,主要介绍了系统在面对大流量冲击的时候,如何进行请求的削峰。有三种处理方式
-
通过队列缓冲请求
-
通过答题延缓请求发生时间,并且做出校验,过滤到不符合条件的请求。
-
分层过滤
三种方式中依靠队列来缓冲请求,是最通用的处理方式,能够较好的保护内部系统的稳定,解决请求不平缓的场景。当然,用到队列后,如何处理好用户的请求,保证用户体验,也是需要大家重点去了解去考虑的。
最后,如果本文对你有帮助,欢迎点赞收藏评论,每一个评论我都会认真回答。也欢迎加我的wx:Ldhrlhy10,加我进群,一起进步,一起对抗互联网寒冬。