怎么设计一个秒杀系统

方向:将请求尽量拦截在系统上游

思路:限流和削峰

1、限流:屏蔽掉无用的流量,允许少部分流量流向后端。

2、削峰:瞬时大流量峰值容易压垮系统。常用的消峰方法有异步处理、缓存和消息中间件等技术

  • 异步处理:秒杀系统是一个高并发系统,采用异步处理模式可以极大地提高系统并发量,其实异步处理就是削峰的一种实现方式。
  • 缓存:秒杀系统本身是一个典型的读多写少的应用场景【一趟火车其实只有2000张票,200w个人来买,最多2000个人下单成功,其他人都是查询库存,写比例只有0.1%,读比例占99.9%】,非常适合使用缓存。
  • 消息队列:消息队列可以削峰,将拦截大量并发请求,这也是一个异步处理过程,后台业务根据自己的处理能力,从消息队列中主动的拉取请求消息进行业务处理。

前端优化:

1、静态资源缓存 

  •  页面静态化
  • CDN页面缓存,也可以用redis缓存渲染的页面

 2、限流方法

  • 使用验证码,防止机器人、爬虫以及分散用户请求
  • 禁止重复提交 :用户提交之后按钮置灰,禁止重复提交 

后端优化:

1、控制层方面入手

  • 负载均衡 

        使用多个服务器并发处理请求,减小服务器压力。

  • 后端下发秒杀链接

        在秒杀开始前,前端不能得到秒杀地址,防止提前获取地址,模拟秒杀请求

  • 限制同一个用户id访问频率
  • 服务降级

        基于令牌桶算法实现限流。令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。

2、服务层

  • 业务分离:秒杀业务系统和其他业务分离,单独放在高配服务器上。防止秒杀系统影响其他业务系统
  •  采用消息队列缓存请求:将大流量请求写到消息队列缓存,利用服务器根据自己的处理能力主动到消息缓存队列中抓取任务处理请求,数据库层订阅消息减库存,减库存成功的请求返回秒杀成功,失败的返回秒杀结束。

  • 利用缓存应对读请求:对于读多写少业务,大部分请求是查询请求,所以可以读写分离,利用缓存分担数据库压力。

  • 利用缓存应对写请求:缓存也是可以应对写请求的,可把数据库中的库存数据转移到Redis缓存中,所有减库存操作都在Redis中进行,然后再通过后台进程把Redis中的用户秒杀请求同步到数据库中。可以将缓存和消息中间件 组合起来,缓存系统负责接收记录用户请求,消息中间件负责将缓存中的请求同步到数据库。

 可以使用redis的减操作,初始化库存数,每一个请求减1,然后将请求放在消息队列中。如果返回结果小于0(为了防止少卖现象,可以多存放一些请求进消息队列,即将阈值0改小),则认为活动结束,返回客户端。

猜你喜欢

转载自blog.csdn.net/m0_37450089/article/details/93380432