【高并发秒杀架构】秒杀系统核心设计梳理本文为「电商秒杀架构」系列第一篇聚焦秒杀系统的业务本质、核心挑战与设计原则帮助读者建立对秒杀系统的整体认知为后续架构设计与性能优化打基础。一、秒杀系统的三个问题1.1 为什么需要秒杀系统通俗地讲电商平台的本质是在线上撮合买卖双方的购销需求、达成交易。虽然是线上交易但也遵循朴素的经济学原理线下商场为了促进销售一般会采用各种促销让利方式吸引比平常更多的消费者常见的促销方式有单品满减、总价优惠、赠品、会员优惠等。有时很多商品甚至是亏损出售就是为了吸引更多的人气与流量所谓「赔本赚吆喝」。线上交易自然也是如此秒杀正是为了达到这个目的而存在的重要手段。1.2 头部电商平台把秒杀系统放在什么地位在头部电商平台除了售卖爆品外更多售卖的是普通商品。这两类商品特点鲜明爆品具有流量激增的特点普通商品流量则比较均衡。如果这两类商品不加区别、直接在电商平台上一起交易会引发灾难性的后果容易引发平台 P0 级重大事故。究其原因主要就在于秒杀流量是突发式的而且流量规模很难提前准确预估如果混合在一起势必会对普通商品的交易造成比较大的冲击。因此对京东、阿里而言即使需要投入新的资源也需要单独搭建一套秒杀系统它将作为交易体系中非常重要的一个核心系统。1.3 秒杀系统对我们意味着什么秒杀系统是互联网 IT 技术人员绕不开的一个话题。大到京东、阿里这样的头部电商小到新兴的社区团购公司都需要通过秒杀促销活动进行拉新留存或持续引流保持热度。因此对互联网 IT 人员来说设计和开发秒杀系统是一门必修课。一方面这门课程里介绍的一些高可用、高性能、高并发的设计思路遵循普适原则在设计其他系统时你可以举一反三另一方面大部分的面试场景都会考核秒杀系统的设计能力。接下来我们就来看看头部电商的秒杀系统以及我们自己的商城系统中秒杀系统的设计和实现。二、秒杀业务初步分析每年的 618、双 11 都是电商平台的专门促销日各种营销活动、营销方式层出不穷而秒杀就是其中最重要的手段之一。飞天茅台、华为手机、高端显卡等热门商品的抢购活动即使你没有抢过也或许听过这就是秒杀带来的影响力。目的就是用具有价格优势的稀缺商品来增加电商平台的关注度带来空前的流量进而可以为平台的拉新带来新助力如果再辅以其他营销手段比如抢购资格限制 VIP 等这又是一笔可观的创收。所以在当下这个流量为王的互联网时代能够提供秒杀的营销手段就显得异常重要。实现一个秒杀系统并不是那么容易要考虑的点很多首先要知道秒杀活动的业务特点其次要清楚秒杀系统的请求链路根据其特点针对请求链路中可能存在的瓶颈点做优化与设计。通常情况下平台商家会拿出稀缺商品事先在秒杀的运营系统中设置好活动的开始/结束时间以及投入的库存这几个是秒杀主要元素。活动开始之后用户可以通过活动抢购入口一个商品详情页或一个广告链接进入活动的结算页然后点击下单完成商品的抢购操作整个过程如下这种方式通用性很强可以适配大部分的平台。在此基础上还可以按需增强预约功能如果想对流量有个预期管理、方便做备战工作可以加上预约功能——在活动开始前先开放一段时间的预约让用户先去预约然后才能获得参加抢购活动的资格。联合风控如果面对的业务场景更复杂可以联合风控在参加活动时校验用户资质踢掉黄牛以及有过不良行为的用户尽量将资源给到优质用户。搭配限购如果业务再复杂些可以搭配限购开展活动控制个人维度下一段时间内的购买数让抢购触达更多的人。以上各种使用场景可以根据自己的实际情况灵活变通或者开拓思维创造属于自己独特的秒杀玩法。三、秒杀系统的挑战在实现秒杀系统时主要会面临以下三类挑战。3.1 巨大的瞬时流量秒杀活动的特点就是将用户全部集中到同一个时刻一起开抢某个热门商品而热门商品的库存往往又非常少所以持续的时间也比较短快的话可能一两秒内就结束了。这种场景下高并发产生的巨大瞬时流量首先会击垮你服务的「大门」当「大门」被击垮后外面的进不来里面的出不去进而造成整个服务的瘫痪紧接着如果进来的流量不加以管控、任凭其横冲直撞也会对依赖的基础设施服务造成毁灭性打击即使系统没有被摧毁在机器资源的高负载下整个请求链路的响应时间也会跟着拉长大大降低用户的抢购体验紧接着就是蜂拥而来的客诉。本想通过秒杀活动带来正面影响但结果可能恰恰相反。3.2 热点数据问题高并发下无法避开的一个问题就是热点数据问题。特别是对于秒杀活动大家抢购的都是同一个商品所以这个商品直接就被推到了热点的位置这对存储系统是很大的考验。像商品库存的控制就会有这个问题。3.3 刷子流量一般我们提供的秒杀对外服务都是 HTTP 服务。不管你是用 H5 实现的页面还是通过安卓或 iOS 实现的原生页面特别是 H5都可以直接通过浏览器或抓包工具拿到请求数据这样刷子便可以自己通过程序实现接口的直接调用并可以设置请求的频率。这样高频次的请求会挤占正常用户的抢购通道同时刷子也获得了更高的秒杀成功率。这不仅破坏了公平的抢购环境也给系统服务带来了巨大的额外负担。总结瞬时的大流量就是最大的挑战。当业务系统流量成几何增长时有些业务接口加机器便可以支持但考虑到成本与收益在有限的资源下如何通过合理的系统设计来达到预期的业务目标就显得格外重要。四、秒杀系统设计清楚了秒杀系统所面临的挑战接下来我们就可以考虑如何应对了。4.1 一次 HTTP 请求经过的链路在设计系统之前我们要先来看看一次 HTTP 请求所经过的链路路径这是一个比较宏观的图谱。如果我们提供的是一个 HTTP 服务那么每个客户端请求进来都要经过这些链路而每个链路节点的作用又是什么呢我们逐一来看DNS负责域名解析会将你的域名请求指定一个实际的 IP 来处理并且一般客户端浏览器会缓存这个 IP 一段时间当下次再请求时就直接用这个 IP 来建立连接。如果指定的 IP 挂了DNS 并不会自动剔除下次依然会使用它。Nginx也就是上面被 DNS 指定来处理请求的 IP一般都会被用来当做反向代理和负载均衡器使用。因为它具有良好的吞吐性能所以一般也可以用来做静态资源服务器。当 Nginx 接收到客户端请求后根据负载均衡算法默认是轮询将请求分发给下游的 Web 服务。Web 服务这个就是我们都比较熟悉的领域了一般我们写业务接口的地方就是这里还有我们的 H5 页面也都可以放到这里这里是我们做业务聚合的地方提供页面需要的数据以及元素。RPC 服务一般提供支撑业务的基础服务服务功能相对单一可灵活、快速部署复用性高。RPC 服务一般都是公司内部服务仅供内部服务间调用不对外开放安全性高。4.2 秒杀系统的核心能力在了解了一次请求所经过的链路节点后我们再来看在用户的一次抢购过程中每次和系统的交互都要做什么事情。支付部分对于一般平台来说都是通用板块而显示商详页部分头部机构可能这个部分也属于通用板块和从「点击抢购」开始到「下单成功待支付」这一段是属于秒杀系统的业务范畴。梳理下来与秒杀相关的事情主要有秒杀的活动数据参加秒杀活动的商品信息主要用于商详页判断活动的倒计时、开始、结束等页面展示和抢购入口校验。提供结算页如果把秒杀做成一个单独业务模块可跨平台安卓、PC、iOS嵌入那么就需要提供一整套服务包括 H5 页面主要用于展示商品的抢购信息包括商品名称、价格、抢购数量、地址、支付方式、虚拟资产等。提供结算页页面渲染所需数据包括用户维度的地址、虚拟资产等数据活动维度的名称、价格等数据。提供下单用户结算页下单提供订单生成或将下单数据透传给下游。4.3 设计基本原则校验前置、分层过滤对于系统的设计有一些基本的原则比如校验前置、分层过滤大型网站会在DNS 层做一些和网络相关的防攻击措施网络安全部门有统一的配置措施这层无法写业务也和我们没什么太大的关系但是可以拦截一些攻击请求。接下来到Nginx 层。Nginx 不仅可以作为反向代理和负载均衡器也可以做大流量的 Web 服务器同时也是一款非常优秀的静态资源服务器。如果把业务校验也放到这里来就可以实现校验前置。接下来就到了Web 服务。我们在这里做业务的聚合提供结算页页面渲染所需要的数据以及下单数据透传同时也负责流量的筛选与控制保证下游系统的安全。最后就是RPC 服务。它提供基础服务一般经过上面 3 层的严格把关到这里来的请求量已经小很多了。五、秒杀的流量隔离思路从上面的分析可以看到秒杀系统的基础思路是在实现电商业务的基础上通过服务隔离从而对流量进行层层分拆。那么应该如何设计流量隔离策略呢5.1 为什么要隔离普通商品的售卖和秒杀商品售卖最本质的区别是什么显而易见的是流量不同。针对普通商品销量当然是越多越好所以商家备货一般都会很充足这样用户去购买的时间就会分散开流量也会比较均衡。而秒杀商品说白了就是稀缺爆品特点就是库存少因此用户会去抢购刷子也会热情高涨以致瞬时流量巨大。另外普通商品和秒杀商品的数量级也是完全不同的。在头部电商平台几十亿的商品都是普通商品只有少数百个以下的商品具备秒杀商品的特点。面对这样的区别这两类商品其实很难在电商平台上一起进行交易。因为秒杀流量是突发式的而且流量规模很难提前准确预估如果混合在一起势必会对普通商品的交易造成比较大的冲击。需要单独搭建秒杀系统它天然为流量而生。很自然为了不让 0.001% 的爆品影响 99.999% 普通商品的交易我们很快就想到了隔离。隔离是控制危险范围最直接的手段——正如面对超预期瞬时流量我们也要采取很多措施进行流量的隔离防止秒杀流量串访到普通商品交易流程上带来不可预估的灾难性后果。5.2 业务隔离秒杀商品的稀缺性决定了业务不会像普通商品那样进行投放售卖一般会有计划地进行营销策划制订详细的方案以达到预期的目标。因此从业务上看它是和普通商品完全不一样的售卖流程它需要一个提报过程。大部分的电商平台会有一个专门的提报系统商家或者业务可以根据各自的运营计划在提报系统里进行活动提报提供参与秒杀的商品编号、活动起止时间、库存量、限购规则、风控规则以及参与活动群体的地域分布、预计人数、会员级别等基本信息。电商平台的提报过程和这些基本信息对于大厂是比较重要的有了这些信息作为输入技术部门就能预估出大致的流量、并发数等并结合系统当前能支撑的容量情况评估是否需要扩容是否需要降级或者调整限流策略等因此业务隔离重要性也很高。5.3 系统隔离接下来看系统隔离。前面已经介绍过商品交易流程大概会用到哪些系统理论上讲需要把交易链路上涉及到的系统都单独复制部署一套隔离干净。但这样做成本比较高——一般大点的电商平台都采用分布式微服务的部署架构服务数量少则几十个多则几百个全部复制一套进行隔离不现实我们的商城项目自然也无法做到。所以比较常见的实践是对会被流量冲击比较大的核心系统进行物理隔离而相对链路末端的一些系统经过前面的削峰之后流量比较可控了这些系统就可以不做物理隔离。用户的秒杀一定是首先进入商品详情页很多电商的秒杀系统还会在商详页进行倒计时等待时间到了点击秒杀按钮进行抢购。因此第一个需要关注的系统就是商品详情页我们需要申请独立的秒杀详情页域名、独立的 Nginx 负载均衡器以及独立的详情页后端服务。如有可能还需要对域名进行隔离可以申请一个独立的域名专门用来承接秒杀流量流量从专有域名进来之后分配到专有的负载均衡器再路由到专门的微服务分组这样就做到了应用服务层面从入口到微服务的流量隔离。一般来说秒杀中流量冲击比较大的核心系统就是秒杀详情页、秒杀结算页、秒杀下单库存扣减是需要我们重点关注的对象而相对链路末端的一些系统经过前面的削峰之后流量比较可控了如收银台、支付系统物理隔离的意义就不大反而会增加成本。5.4 数据隔离现在我们已经完成了应用层的隔离。接下来在数据层面我们也应该进行相应的隔离否则如果共用缓存或者共用数据库一旦瞬时流量把它们冲垮照样会影响无辜商品的交易。数据层的专有部署需要结合秒杀的场景来设计部署拓扑结构。比如 Redis 缓存一般的场景一主一从就够了但是在秒杀场景需要一主多从来扛读热点数据。