对于某些业务场景来说,往往会把秒杀作为工具用于提升交易量和品牌传播,从而进一步提升用户粘性。顾名思义,秒杀就是在极短的时间内抢购商品,利用限时限量,先到先得的用户心理,刺激购买或机会消耗。

对于这个业务场景来说,我们提炼出来几个关键信息:

(1)最终能抢到商品的人数是固定的(2)服务器处理资源和能力是一定的(3)所有请求中存在一定比例的无效请求

基于上面的状况,对于秒杀这种场景我们需要设计一些规则,从而确保服务的质量。本文介绍的操作思路主要包括消息队列和分层过滤2种。


01

基本原则

削峰从本质上来说就是更多地延缓用户请求,以及层层过滤用户的访问需求,遵从“最后落地到数据库的请求数要尽量少”的原则。

从整体的角度来考虑秒杀场景的话,可以概括为下面的内容:

(1)动静结合:划分好动静资源,静态资源使用CDN进行服务分发(2)消息队列:利用消息队列承接瞬时的流量洪峰,在另一端平滑地将消息推送出去(3)分层过滤:在不同的层次尽可能地过滤掉无效请求,采用“漏斗”式设计来处理请求(4)缓存设计:增加QPS,从而加大整个集群的吞吐量02消息队列

利用消息队列缓冲瞬时流量,把同步调用转换成异步调用,达到削峰填谷的作用,不足之处在于请求处理的延时和处理能力存在上限。

(1)具体操作步骤?


  • 将秒杀请求放入消息队列,响应用户“秒杀结果计算中”
  • 后台启动若干队列处理任务,消费队列中的消息,执行校验入库、下单等业务逻辑

(2)除了消息队列常见的实现方式还有哪些?


  • 内存排队算法的实现方式(先进先出,先进后出)
  • 利用线程池加锁等待的实现方式
  • 把请求序列化到文件中,然后再顺序地读文件(例如基于 MySQL binlog 的同步机制)来恢复请求等方式。

具体的消息队列MQ选型和应用场景可以参考:

分布式消息队列(上):主流MQ的二三事03分层过滤

利用消息队列的方式是从对用户端请求进行缓冲的角度触发的,还可以从消减无效请求的角度触发。

(1)分层过滤的基本原则?


  • 对读数据不做强一致性校验,减少因为一致性校验产生瓶颈的问题

  • 对写数据进行基于时间的合理分片,过滤掉过期的失效请求

  • 对写请求做限流保护,将超出系统承载能力的请求过滤掉

  • 对写数据进行强一致性校验,只保留最后有效的数据


(2)具体操作步骤?

一般来说请求经过的路径分别是:CDN、前台读系统(如商品详情系统)、后台系统(如交易系统)和数据库。整个路径执行过程中,尽量将不影响性能的检查条件提前,例如用户是否具有秒杀资格、秒杀是否结束、请求是否非法、商品状态是否正常等等,最终让“漏斗”最末端(数据库)的才是有效请求。分布式消息队列(下):流量削峰该怎么做_写数据

分布式消息队列(下):流量削峰该怎么做_先进先出_02

【微语】


千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。

——于宙《我们这一代人的困惑》

  
​​分布式消息队列(下):流量削峰该怎么做_先进先出_03分布式消息队列(下):流量削峰该怎么做_写数据_04