简介
什么是秒杀?通俗一点讲就是网络商家为促销等目的组织的网上限时抢购活动。
比如说京东秒杀,就是一种定时定量秒杀,在规定的时间内,无论商品是否秒杀完毕,该场次的秒杀活动都会结束。这种秒杀,对时间不是特别严格,只要下手快点,秒中的概率还是比较大的。
淘宝以前就做过一元抢购,一般都是限量 1 件商品,同时价格低到「令人发齿」,这种秒杀一般都在开始时间 1 到3 秒内就已经抢光了,参与这个秒杀一般都是看运气的,不必太强求。
业务特点及带来的问题
在设计架构之前,我们得去结合业务特点来思考会出现哪些问题?
举个例子,比如我们现场要卖100台mbp,秒杀价为5000,那么如果知名度高的话,可能来抢这个mbp的有十万人。
高并发
一般正常的商家都是利用极低的价格配合短信,app推送等来吸引大量的用户来参与秒杀,所以这个用户量是很大的。如果价格足够香,同时候营销还给力的话那么几十万的流量都是有可能的。
这边就带来第一个问题:高并发。没错,大量的用户会在同一事件进行抢购,网站的瞬时访问流量激增。秒杀最显著的特点就是如此:时间极短,瞬间用户量大。
想想单机的redis一般是三四万的qps,如果再高些就会出问题了,大量的请求进来,带来可能存在的缓存击穿,缓存穿透,缓存雪崩,这些我们都必须有足够的预案来考虑,如果缓存出问题之后,想想这么高的流量直接打到DB,那么单机的DB肯定是要崩的,好好的活动就凉了。
超卖
由于秒杀基本上都是以极低的价格去回馈或者拉人气,所以释放出来的商品数量是有限的,就如上例100台,商家就是利用这100台的低价来赔本赚吆喝,结果如果多卖了几百台呢,如果不发货用户投诉,发货商家血亏,这就是超卖问题。
即访问请求数量远远小于库存适量,所以必须保证有多少库存卖多少,不能出现多于库存的购买成功出现。
恶意请求【接口防刷】
我们思考一下,由于价格低就存在这套利空间,想想之前春节或者明星演唱会的门票被各种黄牛用刷票软件给刷掉。用刷票软件模拟出几十万甚至几百万的请求向后台服务器发起请求,这种一秒中几百次的请求是极其常见的,所以如何防止此类软件重复无效的请求,防止不断发起请求也是我们需要针对考虑的。
秒杀URL【链接暴露】
一般而言,秒杀在时间到来之前都是会把按钮置灰,对于普通用户来讲,看到的只是一个比较简单的秒杀页面,在未达到规定时间,秒杀按钮是灰色的,一旦到达规定时间,灰色按钮变成可点击状态。这样就不会让用户可以点击发起请求。不过这点只是针对小白用户,如果是稍微有点电脑工地的用户,会通过f12看浏览器的network看到秒杀的url,通过特定软件去请求也可以实现秒杀,或者提前知道秒杀url的人,一请求就直接实现秒杀了,所以这点也是我们必须要考虑到的。
数据库设计
每秒上万甚至十几万的QPS(每秒请求数)直接打到数据库,会直接把数据库给干趴下,所以大家都基本有个共识,秒杀是存在把我们服务器击穿的风险,思考一下,如果它和我们其他业务使用是在一个数据库,并且耦合在一起,那么很有可能牵连和影响到其他业务,到时候数据库一宕机把整个网站都搞崩了,所以我们得提前思考如何防止此类事件发生,就算秒杀出现宕机,服务器卡死也要尽量不影响线上的其他应用。
大量请求问题
按照我们之前高并发引入的缓存,就算使用缓存其实还是不足以应对短时间高并发的流量冲击。如何承载极高的qps的同时提供给用户低时延的服务保证。
秒杀系统的设计及技术方案
先罗列一张秒杀的技术架构图
我们代入到用户的角度,从用户准备点击秒杀的阶段开始走一遍链路。
首先从前端开始:
步骤一 资源静态化
资源静态化:
将商品描述,参数,成交记录,图像,评价等全部写入一个静态页面,用户请求不需要通过访问后端服务器,不需要经过数据库,直接在前台客户端生成,这样可以最大可能地减少服务器的压力。把能提前放入cdn服务器的东西都放进去,减少真正秒杀时候的服务器压力。
秒杀的网页内容尽可能做的简单,图片小,js,css体积小数量小,内容上做到动静分离。