首页 > 互联网 > 【高并发编程】如何应对一次突如其来的秒杀活动

【高并发编程】如何应对一次突如其来的秒杀活动

今天上了一个由一位在阿里待过几年的大佬开的相关课程(上的网课,特殊时期大家千万不要到处浪哈),其中聊到08年阿里的域名由原先的alibaba.com变更为1688.com时为了进行快速推广策划部策划了一次秒杀活动,并在离上线时间只有5天的情况下将这个活动的信息知会了技术部门(具体内容不一定准哈,知道有这么一件事情就好,毕竟这是一个技术贴嘛)。之后阿里的一位技术大佬将这个任务应承了下来并给出了一个可行的方案(然后当然就飞黄腾达了)。而这位大佬给出的方案并不是对原有的系统进行重构从而提高其性能(毕竟想想都不现实,否则阿里之前就做了)。而对方使用的方法是对秒杀活动相关的操作做了特殊的处理。


淘宝秒杀页

秒杀过程:秒杀节目在活动当天就可以进行加载,但在到规定时间前该界面中的秒杀按钮置灰,只有在秒杀时间及之后刷新该按钮才变为可点状态。秒杀过程中用户需要点击秒杀页中的秒杀按钮进入商品详情页之后点击其中的下单按钮进入付款页,前56个完成付款者成功秒杀到对应商品。

从上面的过程我们可以知道整个秒杀过程涉及到秒杀页、商品详情页和付款页3个页面,而其中关键操作的促发点分别有秒杀页中的秒杀按钮、商品详情页中的下单按钮和付款页的付款按钮,而其他页面信息均只做展示之用。而这种高并发访问的操作所面对的问题主要是服务器的数据库读写和带宽负载两个方面。所以要优化的过程就是尽可能的减少数据库的读写和用户访问过程中数据的传输量。

针对这两个问题当时负责的大佬进行了以下的优化:

a.缓存机制:秒杀页中除了秒杀按钮是否可选和其操作连接外其他信息均属于可以让用户提前加载的数据,而对这些数据的处理方式就是将其写成静态页面并设置为浏览器可缓存的状态。这样做的好处是用户基本上都会在活动开始前进入秒杀页,而且这个时间是分散的,有人可能提前大半天就进入秒杀页,有人则是提前几分钟进入,而只有在第一次进入时页面会去请求服务器获取页面信息,其他时间则是直接从浏览器缓存里获取到这些信息,所以单位时间内服务器的压力是很小的。

b.减少传输的数据量:秒杀按钮的可点状态的修改是一个很重要的事情,负责方既不能让用户能够提前完成秒杀页的操作从而进入下一步操作,又不能因此带来过大的带宽负荷,最终使用的方法是将进入下一步操作的URL存放到一个jsp页中,每次用户刷新页面时就好去服务器加载该jsp页,在到秒杀时间之前路由器对该请求进行拦截并返回一个空的界面给用户端,只有当秒杀时间到来后请求才能通过路由器并从服务器上请求到包含下一步操作所需的URL的jsp页并使秒杀按钮进入可点状态。在到达秒杀时间前用户每次请求并不会到达服务器端,不会对服务器产生任何对负荷,而每次传输的都是一个空的数据页,这种情况所使用到的带宽也是微乎其微的。而在进入秒杀阶段后加载jsp的过程实际上只需要读取到该jsp界面(具体是通过io读取还是事先将文件缓存到内存中这个课上没有说明,不过按照正常思路应该放内存里,这样就不用使用到io不会出现延时),而jsp文件中只储存了少量的文本信息,其大小在1k以内,所以1G的带宽理论上可以同时负载一百万个用户同时进行数据请求。

c.限流机制:秒杀页的信息可以让用户提前加载,而订单详情页和付款页只有在活动开始后用户点击秒杀按钮拿到对应的token后才能进行加载,而且一次秒杀往往几秒钟内就结束了。为了避免短时间内大量的请求对服务器和带宽等造成过大的压力,这里采用了限流的形式来进行处理。前面说到每个商品其实只有56个名额,也就是说只有前56个付款成功的用户能够抢到商品,而这可以跟马拉松比赛进行类比,在马拉松比赛中会把同一时间赛道内的选手按照所处的位置分为第一梯队,第二梯队等多个梯队,而当一个选手所处的梯队比较靠后的时候,其实这个选手就已经与奖牌无缘了,特别是到了冲刺阶段,除非你处于第一梯队,否则你基本上就没有任何拿到奖牌的希望了。根据这种请求,开发团队对路由器进行了现在,只有前1000个发起的商品详情页请求才会被转发到服务器上,其他请求统一返回秒杀失败信息,而之后只对前100个付款页请求进行转发,其他的均返回秒杀失败信息。当然,最后付款成功的就只有前面的56人了。通过这样的操作,团队很好的做到了在基本公平的情况下将服务器的压力降到最小。

这是一套08年的解决方案,放在今天或许并不惊艳,但是却是当时情况下很好的一套解决方案了。而其中的某些思路无论何时都是值得我们学习的!

本文来自投稿,不代表本人立场,如若转载,请注明出处:http://www.souzhinan.com/hlw/355428.html