如何设计一个秒杀系统??

之前被面试官问到如何设计一个秒杀系统。当时答的不好,后来遇到了一个小伙伴之前做过秒杀系统。经过和大佬的探讨得出了以下的一些设计技巧:

一、只用mysql的秒杀系统?

这种实现的秒杀系统就是通过查询数据库来防止超卖的发生。update t_goods set stock = stock - 1 where good_id = xxx and stock > 0。

前端页面采用java的themlef模板(不用行不行?我就用前后端分离的项目,我就要用vue可不可以,可以,这里我们为了体现后面的优化,所以才说成这个模板做的)。

几千的并发量就能够干死任何版本的单机mysql了。这就是瓶颈。

我们接下来要说的优化,就是为了解决这个瓶颈。

二、优化秒杀系统

我们一般采取两部份优化方式:(1)页面方面(2)接口方面

1、页面方面

页面缓存:

将整个页面以String类型方式存入redis里面。设置过期时间10s,如果有客户端来请求,直接返回缓存中数据,如果缓存失效,再查询数据库,填充页面生成String。

旁边的同学可能板砖要举起来了,你咋把页面变成String类型?themlef有一个resolver了解一下,是可以做到的。

页面静态化:

说白了就是前后端分离项目,什么是前后端分离项目?themlef这种模板引擎肯定不是,因为他是动态的渲染数据。

前后端分离的项目是没有其他的语言规则的,就是html页面通过js的ajax请求然后渲染数据。这个有啥好处?

对于动态渲染的页面,每一次客户端请求都需要完整的从服务端拿取数据,因为里面含动态数据不能缓存到浏览器。

静态页面可以放在浏览器的缓存中,我们不需要请求服务端去拿html页面,在浏览器缓存中直接找到对应的缓存取出,然后通过js去获取数据,进行渲染。这样的方式要比动态页面快的多。因为有些数据是不需要每次都走网络带宽的。例如那些动态页面的静态数据。如果每次都是返回完整html,那么网速会很慢,特别是在秒杀高并发的情境下,更加明显。

压缩css、js:

将css和js压缩,去除中间空白符。尽量将所有的js放到一个js文件,同理css。这样可以一次请求就获取了所有资源,不用多次请求。

2、接口方面

(1)首先前端点击下单的时候,需要填写验证码,这个可以防刷。同时用户下单之后,按钮变灰。

(2)中间可以采用hystrix或者sentinel等进行限流降级操作,不让大批量的请求进入业务程序。

(3)redis会在秒杀之前预热商品的数据,比如商品的基本信息,还会用一个字符串key,value表示一个商品的剩余数。主从+哨兵部署。

(4)当用户下单的时候去查询库存还有没有了,如果有没有,直接返回(卖完,你还买个啥)。如果有,redis的里面商品数量自减(原子操作)。然后返回给订单正排队中,添加到消息队列。

(5)异步执行到mysql刷新商品的库存。update t_goods set stock = stock - 1 where good_id = xxx and stock > 0。同时添加一个订单的信息,其中user_id的字段为唯一索引。那么当用户下单两次的时候,就会发生异常然后回滚。

注意:在这里redis中的库存量是有可能为负数的。我们只需要保证mysql中的永远不会为负数就可以了。因为即使在redis超卖,在mysql也是能够根据stock > 0避免超卖。

 

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值