文章目录
【秒杀系统的接口优化之异步下单】
问题:
针对秒杀的业务场景,在大并发下,仅仅依靠页面缓存、对象缓存或者页面静态化等还是远远不够。数据库压力还是很大,所以需要异步下单,如果业务执行时间比较长,那么异步是最好的解决办法,但会带来一些额外的程序上的复杂性。
思路:
- 系统初始化,把商品库存数量stock加载到Redis上面来。
- 后端收到秒杀请求,Redis预减库存,如果库存已经到达临界值的时候,就不需要继续请求下去,直接返回失败,即后面的大量请求无需给系统带来压力。
- 判断这个秒杀订单形成没有,判断是否已经秒杀到了,避免一个账户秒杀多个商品,判断是否重复秒杀。
- 库存充足,且无重复秒杀,将秒杀请求封装后消息入队,同时给前端返回一个code (0),即代表返回排队中。(返回的并不是失败或者成功,此时还不能判断)
- 前端接收到数据后,显示排队中,并根据商品id轮询请求服务器(考虑200ms轮询一次)。
- 后端RabbitMQ监听秒杀MIAOSHA_QUEUE的这名字的通道,如果有消息过来,获取到传入的信息,执行真正的秒杀之前,要判断数据库的库存,判断是否重复秒杀,然后执行秒杀事务(秒杀事务是一个原子操作:库存减1,下订单,写入秒杀订单)。
- 此时,前端根据商品id轮询请求接口MiaoshaResult,查看是否生成了商品订单,如果请求返回-1代表秒杀失败,返回0代表排队中,返回>0代表商品id说明秒杀成功。
返回结果说明:
前端会根据后端返回的值来判断是秒杀结果。
-1 :库存不足秒杀失败
=0 :排队中,继续轮询
>0 :返回的是商品id ,说明秒杀成功
1.后端接收秒杀请求的接口doMiaosha。
@RequestMapping(value="/{path}/do_miaosha",method=RequestMethod.POST)
@ResponseBody
public Result<In