秒杀系统要点

秒杀系统要点

Posted by A Chang on February 25, 2020

秒杀系统要点

“秒杀”,就是在同一个时刻有大量请求争抢购买同一个商品,并完成交易的过程,其间涉及大量的并发读和并发写,并要求高可靠和高性能的系统支持。

本质是在有限带宽、CPU计算资源,内存资源下,大量请求下的高可靠性有兜底的架构设计
核心理念:通过缓存、异步、限流来保证系统的高并发和高可用
架构上:负载均衡分布式;静态动态资源分离,用CDN
业务层面:预防强依赖被弱依赖拖垮;预防1%的请求影响到另外的99%

秒杀系统的特别点

防止超卖

我们日常的下单过程中防止超卖一般是通过在数据库上实施乐观锁来完成,使用乐观锁虽然比for update这种悲观锁方式性能要好很多,但是还是无法满足秒杀的上万并发需求。实时库存的扣减在缓存中进行,异步扣减数据库中的库存,保证缓存中和数据库中库存的最终一致性。
分布式缓存是redis,因为redis是单线程写,所以也不用担心线程安全的问题,redis自身就能够保证数据的强一致性

熔断限流,不影响其他功能

在提供真正商品秒杀业务功能的app server上,需要进行交易限流、熔断控制,防止因为秒杀交易影响到其他正常服务的提供,我们在限流和熔断方面使用了hystrix,在核心交易的controller层通过hystrix进行交易并发限流控制,当交易流量超出我们设定的限流最大值时,会对新交易进行熔断处理固定返回静态失败报文。

设定了降级开关

对于首页、购物车、订单查询、大数据等功能都会进行一定程度的服务降级,通过这样的降级处理能够很好的保证各个系统在大促期间能够正常的提供最基本的服务,保证用户能够正常下单完成付款。

秒杀系统的架构原则

数据要尽量少

请求的数据包括请求包体和返回包体,字段精简。不管是请求数据还是返回数据都需要服务器做处理,而服务器在写网络时通常都要做压缩和字符编码,这些都非常消耗CPU,所以减少传输的数据量可以显著减少CPU的使用。

请求数要尽量少

这里的请求数包括了页面依赖的CSS/JavaScript、图片、加载这些文件都需要建立连接要做三次握手,另外,如果不同请求的域名不一样的话,还涉及这些域名的DNS解析,可能会耗时更久。所以,减少请求数可以显著减少以上这些因素导致的资源消耗。

路径要尽量短

所谓“路径”,就是用户发出请求到返回数据这个过程中,需求经过的中间的节点数。所以缩短请求路径不仅可以增加可用性,同样可以有效提升性能(减少中间节点可以减少数据的序列化与反序列化),并减少延时(可以减少网络传输耗时)。这里把应用合并部署在一起,是和分布式微服务并不是矛盾的,只是要从中取舍

依赖要尽量少

防止强依赖被弱依赖拖垮,比如优惠券服务无法提供优惠券列表,导致拖垮支付服务是不行的

不要有单点

单点是系统架构的大忌,单点意味着没有备份,风险不可控。避免单点关键点是避免将服务的状态和机器绑定,即服务无状态化,这样服务就可以在机器中随意移动。

如何做好动静分离

用缓存的方式来处理静态数据

  • 分离出动态内容
  • 去掉 Cookie。
    去掉Cookie并不是用户端收到的页面就不含Cookie了,而是说,在缓存的静态数据中不含有Cookie。

将秒杀活动的静态页面提前刷新到CDN节点,通过CDN节点的页面缓存来缓解访问压力和公司网络带宽,CDN上缓存js、css和图片;

动态内容的处理通常有两种方案

  1. ESI 方案(Edge Side Includes):
    即在 Web 代理服务器上做动态内容请求,并将请求插入到静态页面中,当用户拿到页面时已经是一个完整的页面了。这种方式对服务端性能有些影响,但是用户体验较好。
  2. CSI 方案(Client Side Include):
    即单独发起一个异步JavaScript请求,以向服务端获取动态内容。这种方式服务端性能更佳,但是用户端页面可能会延时,体验稍差。

对系统来说,这些操作可以抽象为“读请求”和“写请求”,这两种热点请求的处理方式大相径庭,读请求的优化空间要大一些,而写请求的瓶颈一般都在存储层。

处理热点数据

处理热点数据通常有几种思路:

  1. 优化
  2. 限制
    把热点商品限制在一个请求队列里,防止因某些热点商品占用太多的服务器资源,而使其他请求始终得不到服务器的处理资源。
  3. 隔离
    秒杀系统设计的第一个原则就是将这种热点数据隔离出来,不要让1%的请求影响到另外的99%,隔离出来后也更方便对这1%的请求做针对性的优化。

已知热点,因此可以提前做好预热。

削峰

削峰从本质上来说就是更多地延缓用户请求的发出,以便减少和过滤掉一些无效请求,它遵从“请求数要尽量少”的原则。

削峰的一些操作思路:

  • 排队
  • 答题
  • 分层过滤

这几种方式都是无损。

兜底方案

每个系统和每个环节都应该设置这个兜底方案,对系统做最坏情况下的保护。


对于每秒几十万并发的场景我们一般除了会在技术层面进行优化,更多的会通过其他一些业务手段来进行交易分流来分散整体的高并发访问