首先,用1张流程图简单展示淘宝秒杀系统的业务流程(不涉及技术层面),各位可以自动带入淘宝的双十一秒杀活动,就是一个很典型的高并发下抢单的锁单机制
接下来聊聊如何实现这些功能,如果想更深入理解这些知识,也可以移步阿里高级架构师欧阳修主讲的秒杀项目实战课,欧阳修在首节免费体验课上有深入的讲解。
扫码报名,免费试听
如何解决瞬时大流量高并发?
电商系统一般会设置整点秒杀,如0元抢购、无门槛优惠券等,每逢双十一,就有很多人在朋友圈吐槽淘宝提交订单后转了半天转不出来,转出来后库存已经为0,这是用户的痛点,也是程序员的技术难点。
因为设置了整点秒杀后,一旦优惠力度较大,大量用户会在同一时间抢购,网站流量瞬间激增。服务器、数据库等能承载的 QPS 有限,如数据库一般是单机 1000 QPS,一旦超过了承载值,网站就有可能崩溃。
如鹿晗和关晓彤官宣时导致微博瘫痪,就是个很典型的例子。
解决瞬时大流量高并发的核心思想是分层过滤,分而治之。即在不同的层次尽可能地过滤掉无效请求,让“漏斗”最末端的才是有效请求。
具体方法:
1
页面静态化(Static Page Technology)
秒杀页面由商品信息和前端页面资源组成,前后端分离,页面资源不会经过后端服务器,将前端资源,放入CDN服务器中。
简单来说就是将前端的页面资源放在另一个“篮子”里,不跟秒杀服务器抢“位置”,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。
2
缓存预热( Cache Warm-up )
说人话,将部分业务逻辑写到缓存里,不需要直接读数据库,来减少数据库服务器的压力,这样访问速度会更快。
比如在秒杀活动开始前,提前将设置好秒杀的商品信息、限购数量,库存数量等写入Redis中,同样是减少服务器压力的方式。
3
异步(Asynchronous)化
异步化主要通过消息队列实现。
消息队列是基于生产者(Producer)/消费者(Consumer)模型的组件,用于实现两个不同的系统之间的解耦和异步 (Asynchronous) 操作。生产者可以高速地向消息队列中投递(生产)消息,消费者可以按照自己的节奏去消费生产者投递的消息。
消息队列一般带有重试的能力。可以持续投递,直到消费者消费成功
说人话,不断重复尝试,直到订单提交购买成功。
4
削峰值填谷(Peak Load Shifting)
因为 Redis 和 MySQL 处理能力的巨大差异。实际下沉到 MySQL 的量还是巨大,MySQL 无法承受。一瞬间大量的抢购成功,创建订单请求,对创建订单服务压力过大,会去操作mysql数据库 无法及时处理创建订单请求,导致系统故障。
解决方案依旧是异步化思想,通过消息中间件来削峰填谷,将请求先发往消息队列中,订单服务端根据自己能力再去消费并创建订单。
有限库存,如何防止超卖?
一般来说,秒杀商品都是低价限量,而访问的数量远远大于库存数量,只有极少数人成功。如果卖出的东西超出了库存,就是超卖。
一般来说扣减库存的流程是这样的:
读取库存表,判断库存,然后扣减库存然而在秒杀瞬间大流量并发请求数据库,可能会导致数据库崩溃。
因为秒杀的本质,就是对库存的抢夺。每个秒杀的用户来都去数据库查询库存校验库存,然后扣减库存,就可能导致数据库崩溃。
而MySQL 数据库单点能支撑 1000 QPS,但是 Redis 单点能支撑 10万 QPS。因此我们可以将库存信息加载到Redis中,将MySQL的访问压力转移到Redis上,直接通过 Redis 来判断并扣减库存。
实际上,微博、阿里巴巴、百度、美团、拼多多等都在使用Redis。Redis如今是互联网项目的标配,在面试中非常高频被问到。使用Redis的原理是:
  1. 缓存库存信息,大部分数据读取请求都被 Redis 挡住了,保护了MySQL。
  2. 检查 Redis 库存和扣减 Redis 库存是两步操作,通过Lua脚本将这两步操作,合并成一个整体,保证原子操作性。
  3. 哪怕 Redis 侧方行,可以创建订单了,到 MySQL 的时候也需要再检查一次。

如何保证系统稳定和高可用?
秒杀开始时,还会遇到以下问题:
问题1:当秒杀的用户量超过预计,请求量超过服务器最大承载压力怎么办?
问题2:当有服务出现故障,不可用时如何应对?
这时候就要启动系统保护措施
1.限流,流量控制
2.服务熔断
对于秒杀系统来说,秒杀时请求瞬间的秒杀流量是不可控的,没办法准确预估多少,但是秒杀系统的处理能力是有限的,当流量过大时服务器会被打挂。
流量控制(flow control)
其原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,保护系统不会被压垮,从而保障应用的高可用性。
服务熔断
熔断这一概念来源于电子工程中的断路器(Circuit Breaker)。在互联网系统中,当下游服务因访问压力过大而响应变慢或失败,上游服务为了保护系统整体的可用性,可以暂时切断对下游服务的调用。
这种牺牲局部,保全整体的措施就叫做熔断。
熔断器,如同电力过载保护器,在一段时间内侦测到许多类似的错误,就会强迫其以后的调用该服务的快速失败,不再访问该服务,从而防止应用程序不断地尝试执行可能会失败的操作。当检测到该节点微服务响应正常后恢复调用链路。
此外,关于如何防止黄牛和恶意请求、如何限制用户购买件数、秒杀系统的代码实现方式,阿里巴巴高级架构师欧阳修在《秒杀项目实战课》上讲得很清楚了,感兴趣的朋友可以去免费试听体验一下。
↓↓扫码免费试听第一节课
戳下方
阅读原文”免费试听课程
继续阅读
阅读原文