Skip to content

Latest commit

 

History

History
185 lines (91 loc) · 6.35 KB

84.亿级架构实操:亿级秒杀系统的业务架构、流量架构、数据架构.md

File metadata and controls

185 lines (91 loc) · 6.35 KB

亿级架构实操:亿级秒杀系统的业务架构、流量架构、数据架构

秒杀场景的流量特点

  1. 巨大的突发流量
  2. 巨大的后端无效流量

商品维度限流

网关层对除了userId做限流外,还要从商品skuid维度限流

在实际访问量超过预估访问量是,整体限流可以起到保护作用,避免系统被压垮

一旦秒杀开始,实际秒杀成功的用户只是库存的数量,在库存没有之后,将前端的秒杀入口关闭。

写流量处理

诀窍

  1. 有效流量过滤,过滤出有效请求
  2. 有效流量削峰,有效请求,达到或者超出下一层的能力瓶颈,同步处理,变成(降级为)异步处理
  3. 有效流量限流,1000qps,接入层,服务层,数据库

秒杀两阶段操作

  1. 第一阶段为有效流量的锁定,将有效的流量识别出来,过滤掉无效的流量
  2. 第二阶段为有效流量落地,将有效流量,落地到服务层

异步削峰和限流保护

异步削峰

秒杀系统是一个高并发系统,采用异步处理模式可以极大的提高系统并发量,其实异步处理就是削峰的一种实现方式。

场景, 10w人抢10000个商品

两段式操作,参考一下:

  1. 第一阶段为有效流量锁定,将有效的流量识别出来,过滤掉无效的流量
  2. 第二阶段为有效流量落地,将有效流量,落地到服务层

有效流量也很大,比如100w人抢10w商品,如何提升下单阶段的性能呢?

消息队列削峰,其集群吞吐量可以达到100wqps。

限流保护

超出了用户的忍耐度,或者超出系统的承受能力。

可以使用redis分布式限流或者sentinel进行限流。

缓存层 (分布式缓存)

读请求:商品信息提前缓存

参加秒杀活动的商品是提前预知的,可以将参加秒杀的商品信息实现缓存到redis等缓存系统中,这样可以大大的提升系统的吞吐量,减少关系型数据库的读写压力。

为了极致的提高速度,最好是推送到ng的本地缓存

这中间的数据一致性,消息队列的作用,非常大

三级缓存

为了解决以上可能出现的问题,让缓存层更稳定,健壮,我们可以引入三级缓存架构。

  1. 一级缓存为本地缓存,或者进程内的缓存(如同时指出Ehcache2.X, Ehcache3.x,Guava,Caffeine)速度快,进程内可用
  2. 二级缓存为集中式缓存,如redis,可同时为多节点提供服务
  3. 三级缓存为接入层Nginx本地缓存,速度快,进程内可用

原则

尽量命中Ng缓存,最坏也要命中redis分布式缓存

秒杀的功能分离

秒杀只是系统中的一部分

在秒杀系统中,这里需要区分为突发流量型和平缓流量型的功能,从业务上把秒杀和日常的售卖区分开来,对突发流量的功能做好隔离。

把秒杀作为营销活动,要参与秒杀的商品需要提前报名参加活动,这样我们就能提前知道哪些商家哪些商品要参与秒杀,对应于秒杀系统的核心功能,比如,商品详情,下单等。

系统架构(分层)

  1. 客户端: 客户端层是浏览器或者手机应用app
  2. 接入层:系统入口,负载均衡,反向代理
  3. 服务层:实现核心应用逻辑,返回html或者json
  4. 缓存层:缓存加速访问存储
  5. 数据库层:结构化db和异构db
  6. 中间件:zk,xxl-job,rocketmq

漏斗型

漏斗型业务,指的是,用户的请求从客户端到db层,层层递减,递减的程度按照业务而定。

比如,10w人抢购100个商品,db层的请求在在为数量级1000内,这是比较理性的模型。

静态数据

对于读请求,争取到接入层解决,比如商品静态处理,或者放到ng缓存中,流量走cdn。

亿级用户,10wqps,走到ng,那么就是 lvs + 10-20个ng,就可以搞定

动态数据

接入层搞定,ng + 本地缓存/分布式缓存

这种模型下,每一层都要怎么处理

客户层

前端: 做静态页面的缓存,禁止重复提交

秒杀开始后,可以对用户点击后响应前按钮置灰。

为啥要禁止重复提交呢?

如果用户秒杀失败了,频繁重试,会增加后端的压力,可能造成雪崩。

接入层

安全问题:

DDos攻击是通过大量合法的请求占用大量用户网络资源,以达到瘫痪网络的目的,一旦你的网站被人ddos攻击,网站就会无法访问,严重时服务器都能卡死。

本地缓存

使用场景: 秒杀商品动态数据的,读高并发

本地缓存的数据一致性策略:

  1. 秒杀系统的商品是提前预知的,可以将参加秒杀的商品信息提前缓存到redis等缓存系统中,还可以先缓存到nginx的本地缓存(三级缓存),这样可以大大的提高系统的吞吐量
  2. 如果三级缓存没有,再从二级缓存中读取,会写到三级缓存

要点:

  1. 读请求尽量命中nginx的本地缓存
  2. Nginx还需要对商品详情接口做限流保护(根据商品限流),比如限制在1w qps,超过后降级,返回兜底的提示信息,前端可以做出重试,或者提示稍后重试

秒杀限流

ng接入层维度限流

当用户流量远远大于ng瓶颈时,可以随机丢弃请求。

单用户限流

在网关层对下单等接口按照userid进行限流, (接口防刷

假设限制同一个用户10分钟只能下一次单,一般情况下10分钟内,商品早就被抢光了,用户也就没有再次下单的机会了

可以结合风控系统,在网关层吧羊毛党等有问题的用户请求直接拒掉 (拦截恶意用户请求)

整体限流

网关层除了对userId做限流之外,还有从商品skuid维度限流。

在实际访问量超过预估访问量时,整体限流可以起到保护作用,避免系统被压垮

一旦秒杀开始,实际秒杀成功的用户只是库存的数量,在库存没有之后,将前端的秒杀入口关闭。