商城系统 注册

商城秒杀系统设计方案

2018-10-25|HiShop
导读:现在很多电商网站都会提供秒杀系统,用于节日营销的利器,秒杀时可以是网站瞬间访问流量激增,促销效果特别好,那么这种商城秒杀系统应该如何做,下面是hishop小编为大家介绍的...

最新消息,10月24日,手机天猫宣布全面升级,基于用户地理位置自动聚合周边商圈、体验活动、门店好货和消费者权益,形成集线上购物、智慧商圈生活、用户场景体验为一体的新零售城市生活应用,未来有望成为阿里新零售城市生活入口。

现在很多电商网站都会提供秒杀系统,用于节日营销的利器,秒杀时可以是网站瞬间访问流量激增,促销效果特别好,那么这种商城秒杀系统应该如何做,下面是hishop小编为大家介绍的商城秒杀系统设计方案

  商城秒杀系统场景特点

  秒杀时大量用户会在同一时间同时进行抢购,网站瞬时访问流量激增。

  秒杀一般是访问请求数量远远大于库存数量,只有少部分用户能够秒杀成功。

  秒杀业务流程比较简单,一般就是下订单减库存。

  商城秒杀架构设计理念

  限流: 鉴于只有少部分用户能够秒杀成功,所以要限制大部分流量,只允许少部分流量进入服务后端。

  削峰:对于秒杀系统瞬时会有大量用户涌入,所以在抢购一开始会有很高的瞬间峰值。高峰值流量是压垮系统很重要的原因,所以如何把瞬间的高流量变成一段时间平稳的流量也是设计秒杀系统很重要的思路。实现削峰的常用的方法有利用缓存和消息中间件等技术。

  异步处理:秒杀系统是一个高并发系统,采用异步处理模式可以极大地提高系统并发量,其实异步处理就是削峰的一种实现方式。

  内存缓存:秒杀系统最大的瓶颈一般都是数据库读写,由于数据库读写属于磁盘IO,性能很低,如果能够把部分数据或业务逻辑转移到内存缓存,效率会有极大地提升。

  可拓展:当然如果我们想支持更多用户,更大的并发,最好就将系统设计成弹性可拓展的,如果流量来了,拓展机器就好了。像淘宝、京东等双十一活动时会增加大量机器应对交易高峰。

  商城秒杀系统设计方案

  对架构师来说是一大挑战。 只谈技术上的业务描述,秒杀一般分为秒杀前、秒杀中、秒杀后三个阶段,各个阶段的需求如下:

  秒杀前,用户访问秒杀宝贝描述页,不断刷新,等待秒杀开始。

  秒杀中,用户点击秒杀按钮,洪水般的流量瞬间涌入系统,都想走在前面,抢到宝贝。

  秒杀后,秒杀结束,商品已被抢完或者秒杀时间已过,用户访问秒杀结束页面,整个秒杀阶段结束。

  挑战在哪

  秒杀前,大量用户频发刷新秒杀页面,都想第一个看到秒杀开始,越临近开始时间,刷新越频繁,这时候对系统会有巨大的读压力。 秒杀中,用户的秒杀请求短时间内持续涌入,前端访问量暴增,并且会牵扯到写库的需求,还有在对于单一热点商品库存判断和递减,由于写库是排他操作,一个一个排队处理,数据库写压力很大。 秒杀后,和秒杀前差不多,短时间内单页面很多用户访问,但时间一过,页面就没有访问量了。

  所以,方案呢

  对于秒杀前后单页面的大量访问,处理起来很简单,提前预热把秒杀页面放入cdn,大量的请求就可以抗住了。这里有一些需要注意的点。

  一是cdn放的是静态页面,秒杀需要判断秒杀开始,这个可以使用动态加载js的方式(网页),从cdn去请求一个js(秒杀开始后再生成),该js负责跳转到秒杀页面(秒杀开始后再生成,避免作弊),如果是app,可以用webview或者请求一个cdn上的文件也是可以的。有人说为什么不直接请求接口来获取秒杀开始标识,当然是可以的,但是cdn是部署到全国各地的,如果请求服务器,这部分量会占用一部分服务器资源,秒杀诶,能节约资源来进行后续请求就节约啊,不然挂了不好看啊。

  二是怎么判断秒杀是否开始,秒杀基本都是约定好在某个时间点开始,所以一种直接的想法就是靠时间咯。这的确是一种做法,但不是很好,首先是因为秒杀为了分散量,多个商品的秒杀就算是一个时间点,也应该分开进行,这样缓解系统压力;其次就是为了公平性,这个开始时间会在一定范围内有随机性,这样由于用户看到页面的时间随机,不用只拼网速啦,人品也是有用的;还有就是秒杀开始后还有其他工作要做,比如刷cdn放js,生成秒杀页面等,时间在分布式系统里是最不靠谱的了(服务器时间是有差别的),会导致数据问题(比如js生成了,秒杀页面还没有出来,用户一堆404),用户会骂娘的。

  所以一般会抽象一个发令器出来(是的,程序来源于生活。。。),秒杀系统激活发令器,秒杀开始,下游其它业务开始处理,这里可以定义这些业务的处理顺序,秒杀系统里可以配置何时发令,当然也可以有随机的规则。消息中间件出现了,这里发令器发令后,下游的业务就是通过消息中间件得到的秒杀开始的信号!!很多解决不了的问题往往是因为视角不对,以更高的视角看问题,很多问题往往只缺一个抽象。

  秒杀中的最大压力就是对商品库存的并发争抢,就像商场大促销,就那么两件,一堆大妈冲上去抢,各个身怀绝技,商场导购小妹没点武艺还真是抗不住。这时候可以参考之前文章中的异步减库存的形式来做,只是这里是异步下订单。说具体方案之前,先看看这个业务场景要做什么?其实就是在解决一万个人同时拿着钱来东西,但是东西只有十件,你卖给谁的问题,只要没给钱,那我东西不给你就没问题,给了钱就必须拿到东西。

  所以这里我们可以对来买东西的人强制他们排队,先到先得,并且排队的数据少量丢失是可以接受的,后面拍着那么多人呢,不怕卖不完。那最后的方案就是,用户点击秒杀按钮后,加入秒杀队列(限制长度),加入成功则告知正在秒杀,否则直接跳到秒杀结束页面。对于秒杀队列中的用户,则进行写订单减库存处理处理,并且记录成功与失败,商品秒杀完成后,标记秒杀结束,并且可以清空秒杀队列,避免后面重复判断和处理。用户端轮询(可以采用长轮询,时效性好)结果,如果秒杀结束并且自己没有秒杀成功,则跳转到秒杀结束页面,否则继续等待,如果秒杀成功则跳转到秒杀成功页面,支付就是后面的事情了。

  这里有几个点需要关注,一是作弊,就是验证码,各种策略各种造型的验证码;

  二是时效性,秒杀完后一段时间(比如半个小时)没付款,应该将该笔秒杀标记无效,并且把库存回补。消息中间件再次大显身手,秒杀队列,这里需要消息中间件提供限长队列功能(不限长,先查询再入队也是可以的,只是要把握好这个时间间隔可能加入的多余数据对消息中间件的影响),清空队列功能(没有也可以,只是不能更快的释放压力)。当然除了这些,还有限流功能,接入层只允许系统可负载流量进入,超过一定负载就采取措施缓解流量进入(比如验证码。。。)。

  可以看到,对于秒杀中功能,基本就是采取逐级降低流量的方法(大流量系统的重要思路),只让不过分高于有效流量的流量进入后端真正的业务系统,保证业务系统不宕机。还有一个原则就是读比写更容易扩展,无业务系统比业务系统更容易扩展,所以应该化写为读(下订单变为查询订单),降低业务系统压力(前端接入层拦截无效流量)。

电话咨询 预约演示 0元开店