1、秒杀的场景
电商中为了吸引顾客、聚集人气,经常会策划一些秒杀活动。活动中售卖的商品,要么价格远低于市场价格,要么比较稀缺(如一些新发布的商品)。这些商品电商一般都会限量、限时销售。无疑这些商品对消费者的诱惑力是巨大的,消费者蜂拥而来,往往几秒钟就可以将商品抢购一空。而对于电商系统来说可能更多的是考验。
2、传统秒杀系统的痛点
首先,秒杀的场景决定了秒杀是一场速度的比拼,也就是俗话说的“手快有、手慢无”。大家都争着在活动开始后,第一时间将商品抢到,完成下单。因此秒杀活动开始的一瞬间会有大量的流量涌入,几倍、甚至于十几倍的流量对系统的冲击不可谓不大。如果系统没有足够的 capacity 或应对措施,很可能就被瞬时高流量给压垮了。
其次,突如其来的高流量,给系统各个模块都来了一连串的压力,系统可能会因此变慢,而且可能会彼此影响,影响可用性。比如:数据库更新同一个商品库存,需对同一行记录加锁,随着并发的压力逐渐增大,数据库更新的性能是逐渐下降的。从而引起提供库存 service 的应用服务性能下降,连锁的影响到下单 service 的性能,最终反馈到消费者的可能就是整个网站购物流程性能差、响应慢。而面对响应慢的系统,很多消费者可能采取反复刷新,多次尝试,这无疑又增大了对系统的压力。
还有,上述种种给消费者带来的往往是体验上的痛苦。如:网站响应慢,点击抢购按钮没反应。好不容易可以操作了,却发现秒杀活动已经结束,消费者的参与感比较差。久而久之,可能就对此类活动失去了兴趣。
3、1 号店秒杀系统的设计理念
基于以上秒杀场景下的痛点,1 号店的秒杀排队系统在设计时主要考虑以下几点:
- 限流:当秒杀活动开始后,只有少部分消费者能抢购到秒杀商品,意味着其实大部分用户的流量传达到后台服务后都是无效。如果能引导这大部分的流量,不让这大部分的流量传达到后台服务,其实对我们系统的压力就很小了。因此设计思路之一就是,仅让能成功抢购到商品的流量(可以有一定余量)进入我们的系统。
- 削峰:进入系统的有效流量虽然总量不一定是很大的,但却是在很短的时间内涌入的,因此会存在很高的瞬时流量峰值。总量相同的流量在 1 秒钟进入系统,和在 10 分钟均匀地进入系统,对系统的冲击是相差很大的。高峰值的流量往往能将系统压垮。因此另一个设计思路是,如何将进入系统的瞬时高流量拉平,使得系统可以在自己处理能力范围内,将所有抢购的请求处理完毕。
- 异步处理:传统的系统对于请求是同步处理的,即收到请求后立即处理并把结果返回给用户。我们的系统有了削峰的设计后,请求不是被立刻处理的,因此就要求我们能将同步的服务改造成异步的。
- 可用性:我们设计时始终把系统的可用性放在重要的位置,针对系统可能出现的各种状况,都尽最大程度地保证高可用。
- 用户体验:系统设计一定要充分考虑用户体验。消费者点击抢购按钮后,无论是否能抢到商品,期望是能得到及时的反馈。系统上发生任何故障也要尽可能的保证用户体验的损害减到最小。
4、系统架构简介
现在来简单介绍下我们秒杀排队系统的架构,从大的方面来说分为三个主要模块:
- 排队模块:负责接收用户的抢购请求,将请求以先入先出的方式保存下来。每一个参加秒杀活动的商品保存一个队列,队列的大小可以根据参与秒杀的商品数量(或加点余量)自行定义。排队模块还负责提供一系列接口,如:给已进入队列的用户查询下单状态的接口,给调度模块拉取请求的接口,服务模块回写业务处理状态的接口等。
- 调度模块:负责排队模块到服务模块的动态调度,不断检查服务模块,一旦处理能力有空闲,就从排队队列头上把用户访问请求调入服务模块。并负责向服务模块分发请求。这里调度模块扮演一个中介的角色,但不只是传递请求而已。它还担负着调节系统处理能力的重任。我们可以根据服务模块的实际处理能力,动态调节向排队系统拉取请求的速度。作用有点类似水坝的闸门,当下游干旱时就打开闸门多放些水,当下游洪涝时,就放下闸门少放些水。
- 服务模块:是负责调用真正业务处理服务,并返回处理结果,并调用排队模块的接口回写业务处理结果。我们设计这个模块,是为了和后面真正的业务处理服务解耦。目前我们的系统不只支持秒杀抢购这种业务场景,后续有其他适用于排队系统的业务都可以接入,如:领取抵用券等等。同时我们也可以针对后面业务系统的处理能力,动态调节服务模块调用后面业务处理服务的速度。
5、容错处理
任何系统都不可能一帆风顺,但我们要能在出现错误时仍旧保证系统的高用性和良好的客户体验。举几个简单的例子,比如服务模块调用后面服务时,出现调用服务超时怎么办?对此我们设计了对于超时的请求,可以重试的机制。再比如,如果后面真正的业务处理系统宕机怎么办?如果是传统系统的话,可能就面临系统无法使用的尴尬。而我们的系统已经是异步的了,因此加入排队队列的用户请求,在业务处理系统恢复后都可以得到处理。只要我们在前端给用户以友好的交互、提示,系统还是能提供一定质量服务的。
6、用户交互
因为我们的系统设计成异步的,因此消费者不再是像以前一样同步地去等待反馈。消费者需要一个途径来获取抢购的状态和进度。我们的主体流程大体上分为几个阶段:
- 当等待人数大于 500 人,页面提示:排在您前面的人超过 500 位;
- 当等待人数小于等于 500 人,页面提示:您已挤进第 *** 位;
- 当等待时间大于等于 1 分钟,页面提示:剩余时间约 * 分钟。每次以分钟倒计时。
- 当等待时间小于 1 分钟,页面提示:预计剩余 * 秒。
- 抢购成功,后续跳转到订单支付页面
下面仅挑选 2 个 PC 端页面交互的设计供大家参考,
当然我们还提供了一些分支流程的提示与处理,如果大家感兴趣,更详细的情况可以到 1 号店亲自参与秒杀活动来体验。
7、总结
目前我们的秒杀排队系统已经应用于 1 号店的历次大促,并取得了良好的效果,受到业务运营和消费者一致的好评。优秀的系统一定是建立在对业务透彻理解的基础上,针对业务的场景与痛点,结合现有的技术有针对性的提供解决方案。同时技术上成功的系统,往往也推动着业务的发展,给业务更好的支撑和推动。
感谢郭蕾对本文的策划和审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。
评论