秒杀系统的两种设计方案

秒杀系统面临的挑战

秒杀活动和类似的抢购活动中,用户会在短时间内集中操作。后台系统可能在一瞬间面临平时几十倍甚至上百倍的并发请求。如果后台系统没有没有足够的冗余资源的话,系统可能被一瞬间搞瘫痪。如何应对短时间内的请求洪峰,让系统正常工作,是一个秒杀系统需要应对的严峻挑战。由于秒杀任务面临的请求是瞬时的,扩充机器数量是不合理的也不划算。如何在现有硬件条件下,应对秒杀活动的海量请求需要从业务流程方面进行优化。

下面介绍两种秒杀系统解决问题的设计思路。

1.分布式CDN边缘节点

促销活动中客户端会不停的请求服务端来判断活动是否开始,如果所有的请求都引流到一个服务器上,任何一个单一的服务端都响应不过来。这是候就需要将请求放到别的地方去。我们可以引入CDN,在CDN上部署边缘节点,也就是一些小服务,这些服务主要负责通知各个客户端,秒杀活动是否开始了。同时边缘节点也可以用来统计到底有多少人参加了秒杀活动,统计数据通过网络传输给数据中心。

边缘节点过一段时间向数据中心,发送一下参与秒杀活动的人数,这样当秒杀活动开始的时候数据中心就知道有多少人参与了秒杀活动。

假设有100万人参加了活动,而商品只有1万件。这样秒杀活动中签的概率是0.01,活动开始的时候,数据中心向边缘节点发送一个概率0.01。这样CDN上的节点会直接对请求进行过滤,只有0.01的用户会被发送到数据中心,其它的请求会直接返回秒杀失败。

这种秒杀方案的优点是实现简单,容易操作,成本比较低。但是由于边缘节点是直接通过概率筛选的,并没有把所有请求排序按照顺序取前一万名,所以说如果较真的话这种方案并不是一个公平的方案。但是考虑到请求的网络延时,以及请求的爆发数量,在短时间内也很难认定,到底是谁先发起的请求。所以该方案也一种可行的方案。

2.采用消息队列以时间换空间

采用消息队列的方式其实比较好理解,秒杀活动开始的时候,我们可以将请求放到消息队列中,然后后台以固定的速度进行处理。等待处理完毕之后再通知用户进行后续的付款操作。

将短时间内的用户请求,放到一个相对来说更长的时间段内来进行处理,以时间换空间,可以缓解服务端的压力。假如流量在1~2分钟内集中爆发,我们将其延长到10分钟处理,这样服务端的压力就变成了原先的十分之一左右,这样服务端处理起来就可以从容不破了。

为了缓解用户在等待秒杀结果的过程中的焦虑心情,我们可以加入一个排队系统,让用户知道自己处在队列中什么位置,以及前面有多少个人正在处理。

这样对于用户来说,在前台下单一次就可以了,然后等系统慢慢处理,这也符合先到先得的原则,非常公平合理。对系统来说,只要根据大促的商品总量,一定程度上增强系统处理能力,保证下单请求从进来到最后处理完成,这个时间相对合理就可以了。

请求的流程图如下:

队列系统建议使用的是Redis,而不是MQ。因为相对于MQ来说,Redis更轻量级,性能更好,同时Redis它内置了队列数据结构,除了具有MQ的队列特性以外,我们还可以获得队列的长度。我们可以通过队列长度和自己的编号,实时查询自己的排队位置,为等待界面提供对应的排队信息。同时Redis支持多个队列,如果有多个商品参加秒杀活动的话,我们可以为每一个商品建立一个队列,这样存取起来会很方便。

队列长度按照秒杀商品的总数,一比一建立,如果队列中的用户请求数满了,用户再下单会直接返回失败。如果中途有人放弃了秒杀,队列会腾出一个额外的空间,允许下一个请求进入。

通过这种消息队列+异步化处理的方式,我们将秒杀系统的短时间内的海量请求放到一个更长的时间内进行处理, 对流量进行削峰,保证了系统的高性能。这样系统不需要做大修改就能满足对应的需求,同时对下游的业务影响也比较小。

参考资料:

1. 王庆友-高性能架构案例:如何设计一个秒杀系统?

2. 王皓-性能设计中的秒杀

3. 李运华-《从零开始学架构》

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农飞飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值