按关键词阅读:
何为“秒杀”及其特点“秒杀”这一业务场景在如今已经不是什么新鲜名词 , 它本质上属于短时突发性高并发访问问题 , 业务特点如下:
- 定时触发 , 流量在瞬间突增
- 秒杀请求中常常只有部分能够成功
- 秒杀商品数量往往有限 , 不能超卖 , 但能接受少卖
- 不要求立即返回真实下单结果
1.定时触发 , 流量在瞬间突增
这不难理解 , 秒杀活动往往伴随着固定的节日、活动而开展 , 在某一个确定时间对C端用户开放访问能力 , 此时往往会出现一个较为明显的请求激增 。 如:每年“双11”当天0点 , 淘宝等电商平台访问量基本上会出现明显的请求波峰 , 这与秒杀的定时性 , 息息相关 。
2.秒杀请求中常常只有部分能够成功
这是肯定的 , 在库存有限、请求接收较多的情况下 , 常会存在部分请求处理成功 , 部分请求处理失败的情况 。
如果库存是无限的 , 也就不存在秒杀这一说了 。 也正是因为库存有限 , 平台以此为卖点 , 采取定时限量售卖的营销策略更能刺激用户进行访问 。
一般情况 , 秒杀场景下的商品售价较平时都有明显的优惠 。
3.商品数量往往有限 , 不能超卖 , 但能接受少卖
商品数量有限在上文已经说过了 , 我们聊聊“超卖”、“少卖”的问题 。
超卖是不能容忍的情况 , 如果发生超卖 , 则属于业务异常了 。 一般情况下商家只会提供有限数量的商品作为秒杀营销商品 , 如果超卖 , 则商家往往面临较为明显的亏损 。 这在业务上是不能出现的 。
少卖则是能够接受的 , 比如商家提供了10台IPhoneX作为秒杀库存 , 由于临时减库存或其他原因(往往都是业务上的原因)调整只卖了9台 。 这对商家而言并没有多大的损失 , 商家还可以以更高的价格去售卖该多余库存 , 而且平台因为该秒杀活动还收获了较高的PV/UV , 总体而言是没有损失的 。
因此我们在设计秒杀架构的时候要以 “超卖零容忍 , 少卖能兼容” 这一设计原则进行设计 。
4.不要求立即返回真实下单结果
由于秒杀业务的特殊性–短时超高并发 , 因此我们不能按照传统的交易场景进行设计 。
传统交易场景下 , 对于用户的下单请求一般都是同步处理 , 即同步落库持久化 , 并同步返回收单结果 。
如果我们对秒杀订单采用同步持久化的做法 , 则系统的吞吐量将基本依赖DB的性能 , 这在成本上、性能上都有较大压力 。 因此 , 我们要在尽量提高系统收单入口吞吐量的同时降低系统开发部署的成本 。
“不要求立即返回真实下单结果” , 也就是不需要立即持久化 , 换言之也就是业务流程 “异步化”。
明确了流程可以异步化 , 解决的手段就多了 。 利用缓存、队列、线程池都能实现业务的异步化 。 这里也反映出
技术是围绕业务运转的 , 没有业务作为支撑 , 无论技术多么新颖、其性能多么高 , 它都无用武之地 。
秒杀业务概述通过对秒杀核心业务流程进行异步化 , 我们能够将主流程分为收单、下单两个阶段 , 业务流程概括起来如下:
秒杀流程–收单
- 用户访问秒杀入口 , 将秒杀请求提交给秒杀平台收单网关 , 平台对秒杀请求进行前置校验
- 校验通过后 , 将下单请求通过缓存/队列/线程池等中间层进行提交 , 在投递完成同时的同时就给用户返回“排队中”
- 对于前置校验失败的下单请求同步返回秒杀下单失败
秒杀流程–下单
下单流程中 , 平台的压力通过中间层的缓冲其实已经小了很多 , 之所以会少 , 一方面是因为在用户下单的同步校验过程中就过滤掉了部分非法请求;另一方面 , 我们通过在中间层做一些限流、过滤等逻辑对下单请求做限速、压单等操作 , 将下单请求在内部慢慢消化 , 尽可能减少流量对平台持久层的冲击 。 这里其实就体现了中间层“削峰填谷” 的特点 。
基于上述前提 , 我们简单总结下秒杀下单部分的业务逻辑 。