大厂必会之秒杀架构解读

秒杀的真面目

  • 秒杀其实主要解决两个问题,一个是并发读,一个是并发写。秒杀系统本质上就是一个满足大并发、高性能和高可用的分布式系统。

秒杀系统的注意的五大架构原则

4要1不要
1.数据要尽量少
  • 首先是指用户请求的数据能少就少。因为首先这些数据在网络上传输需要时间,其次不管是请求数据还是返回数据都需要服务器做处理,而服务器在写网络时通常都要做压缩和字符编码,这些都非常消耗 CPU,所以减少传输的数据量可以显著减少 CPU 的使用。
2.请求数要尽量少
  • 用户请求的页面返回后,浏览器渲染这个页面还要包含其他的额外请求,比如说,这个页面依赖的 CSS/JavaScript、图片,以及 Ajax 请求等等都定义为“额外请求”,这些额外请求应该尽量少。 例如,减少请求数最常用的一个实践就是合并 CSS 和 JavaScript 文件,把多个 JavaScript
    文件合并成一个文件,在 URL 中用逗号隔开(https://g.xxx.com/tm/xxb/4.0.94/mods/??module-preview/index.xtpl.js,module-jhs/index.xtpl.js,modulefocus/index.xtpl.js)。这种方式在服务端仍然是单个文件各自存放,只是服务端会有一个组件解析这个 URL,然后动态把这些文件合并起来一起返回。
3.路径要尽量短
  • 所谓“路径”,就是用户发出请求到返回数据这个过程中,需求经过的中间的节点数。
4.依赖要尽量少
  • 所谓依赖,指的是要完成一次用户请求必须依赖的系统或者服务,这里的依赖指的是强依赖。
5.不要有单点
  • 系统中的单点可以说是系统架构上的一个大忌,因为单点意味着没有备份,风险不可控,我们设计分布式系统最重要的原则就是“消除单点”。应用无状态化是有效避免单点的一种方式,但是像存储服务本身很难无状态化,因为数据要存储在磁盘上,本身就要和机器绑定,那么这种场景一般要通过冗余多个备份的方式来解决单点问题。

不同场景下面的架构

简单的秒杀系统
  • 在用户页面提供一个秒杀按钮,到时间了就可以进行秒杀。
1w/s-10w/s量级QPS
  • 将秒杀系统独立出来,并做成集群,将热点数据放在缓存中,增加秒杀答题防止秒杀机器抢单。
100w/s的量级的QPS
  • 对页面进行彻底的动静分离,使得用户秒杀时候不用刷新整个页面,客户端对秒杀商品进行缓存,增加系统限流保护。
具体的场景具体分析
  • 秒杀的场景来说,不同QPS量级下瓶颈也会不一样,10w级别可能瓶颈就在数据读取上,通过增加缓存一般就能解决,如果要到100w那么,可能服务端的网络可能都是瓶颈,所以要把大部分的静态数据放到cdn上甚至缓存在浏览器里

优化的具体方案-如何做好动静分离

将静态数据缓存到离用户最近的地方
  • 1,浏览器、2,CDN、3,服务器端的Cache。
静态化改造就是要直接缓存 HTTP 连接
  • 静态化改造是直接缓存 HTTP 连接而不是仅仅缓存数据,Web 代理服务器根据请求 URL,直接取出对应的 HTTP 响应头和响应体然后直接返回,这个响应过程简单得连 HTTP 协议都不用重新组装,甚至连 HTTP 请求头也不需要解析。
让谁来缓存静态数据也很重要
  • 不同语言写的 Cache 软件处理缓存数据的效率也各不相同。以 Java 为例,因为 Java 系统本身也有其弱点(比如不擅长处理大量连接请求,每个连接消耗的内存较多,Servlet 容器解析 HTTP 协议慢),所以你可以不在 Java 层做缓存,而是直接在 Web 服务器层上做,这样你就可以屏蔽 Java 语言层面的一些弱点;而相比起来,Web 服务器(如 Nginx、Apache、Varnish)也更擅长处理大并发的静态文件请求。
在哪些方面做动静分离
  • URL 唯一化。商品详情系统天然地就可以做到 URL 唯一化,比如每个商品都由 ID 来标识,那么 http://item.xxx.com/item.htm?id=xxxx 就可以作为唯一的 URL 标识。为啥要 URL 唯一呢?前面说了我们是要缓存整个 HTTP 连接,那么以什么作为 Key 呢?就以 URL 作为缓存的 Key,例如以 id=xxx 这个格式进行区分。
  • 分离浏览者相关的因素。浏览者相关的因素包括是否已登录,以及登录身份等,这些相关因素我们可以单独拆分出来,通过动态请求来获取。
  • 分离时间因素。服务端输出的时间也通过动态请求获取。
  • 异步化地域因素。详情页面上与地域相关的因素做成异步方式获取,当然你也可以通过动态请求方式获取,只是这里通过异步获取更合适。
    = 去掉 Cookie。服务端输出的页面包含的 Cookie 可以通过代码软件来删除,如 Web 服务器 Varnish 可以通过 unset req.http.cookie 命令去掉Cookie。注意,这里说的去掉Cookie 并不是用户端收到的页面就不含 Cookie 了,而是说,在缓存的静态数据中不含有 Cookie。
缓存架构
  • 实体单机部署:部署服务器集群,单机上面存在Cache
  • 统一Cache层:单独做Cache集群。
  • CDN

二八原则:有针对性地处理好系统的“热点数据”

静态热点数据
  • 动态热点数据:通过报名预约或者大数据分析就能将静态热点数据提前加载缓存中。
动态热点数据
  1. 构建一个异步的系统,它可以收集交易链路上各个环节中的中间件产品的热点 Key,如Nginx、缓存、RPC 服务框架等这些中间件(一些中间件产品本身已经有热点统计模块)。
  2. 建立一个热点上报和可以按照需求订阅的热点服务的下发规范,主要目的是通过交易链路上各个系统(包括详情、购物车、交易、优惠、库存、物流等)访问的时间差,把上游已经发现的热点透传给下游系统,提前做好保护。比如,对于大促高峰期,详情系统是最早知道的,在统一接入层上 Nginx 模块统计的热点 URL。
  3. 将上游系统收集的热点数据发送到热点服务台,然后下游系统(如交易系统)就会知道哪些商品会被频繁调用,然后做热点保护。这里我给出了一个图,其中用户访问商品时经过的路径有很多,我们主要是依赖前面的导购页面(包括首页、搜索页面、商品详情、购物车等)提前识别哪些商品的访问量高,通过这些系统中的中间件来收集热点数据,并记录到日志中。
    在这里插入图片描述

流量削峰这事应该怎么做?

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

排队
  • 1.消息队列,
  • 2.利用线程池加锁等待也是一种常用的排队方式;
  • 3.先进先出、先进后出等常用的内存排队算法的实现方式;
  • 4.把请求序列化到文件中,然后再顺序地读文件(例如基于 MySQL binlog 的同步机制)来恢复请求等方式。
答题
  • 第一个目的是防止部分买家使用秒杀器在参加秒杀时作弊。
  • 第二个目的其实就是延缓请求,起到对请求流量进行削峰的作用,从而让系统能够更好地支持瞬时的流量高峰。
分层过滤
  • 分层过滤的核心思想是:在不同的层次尽可能地过滤掉无效请求,让“漏斗”最末端的才是有效请求。

影响性能的因素有哪些?又该如何提高系统的性能?

影响系统的因素
  • IO、网络、CPU、内存。
优化系统
  • 减少编码,Java的编码运行是比较慢的,涉及到字符串和字节之间的转换,对网页的输出直接进行流输出。
  • 减少序列化:可以采用合并部署,将应用放置在同一个tomcat容器中避免RPC。
  • Java 极致优化
    1.直接使用 Servlet 处理请求。避免使用传统的 MVC 框架,这样可以绕过一大堆复杂且用处不大的处理逻辑,节省 1ms 时间(具体取决于你对 MVC 框架的依赖程度)。
    2.直接输出流数据。使用 resp.getOutputStream() 而不是 resp.getWriter() 函数,可以省掉一些不变字符数据的编码,从而提升性能;数据输出时推荐使用 JSON 而不是模板引擎(一般都是解释执行)来输出页面。
  • 并发读优化:用Cache进行冷热数据+动静数据。

减库存设计

常见的几种方式
  • 下单减库存:比较安全
  • 付款减库存:存在用户下单之后,无法付款
  • 预扣库存:下单之后生成订单,订单会有时间保留,不付款则会失效。
如何限制超卖
  • 事务、库存设置无符号整数、CASE WHEN

如何设计兜底方案?

  • 降级,就是当系统的容量达到一定程度时,限制或者关闭系统的某些非核心功能,从而把有限的资源保留给更核心的业务。
  • 限流,如果说降级是牺牲了一部分次要的功能和用户的体验效果,那么限流就是更极端的一种保护措施了。限流就是当系统容量达到瓶颈时,我们需要通过限制一部分流量来保护系统,并做到既可以人工执行开关,也支持自动化保护的措施。
  • 拒绝服务
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿联爱学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值