黑马点评07 秒杀优化 加阻塞队列

实战篇-22.秒杀优化-异步秒杀思路_哔哩哔哩_bilibili

1.流程回顾

1.1超卖问题

判断秒杀时间,加乐观锁(比较标记/版本),检查库存是否大于0        

1.2一人一单问题

看看数据库里有没有这个这个人下的订单:

1.单机模式中加悲观锁sychronized,锁监视器和用户线程id字符串绑定,购买之前检查。

2.多线程模式有并发安全问题,要加分布式锁才能在不同jvm之前唯一标识一把锁,

通过uuid + 线程id去唯一标识一个线程,避免其他线程误删;

通过lua脚本保证原子性(加锁和设置过期/线程id判断和解锁)

黑马点评06分布式锁 2Redisson-CSDN博客

多线程分布式锁可以用Redission来替代,并且能够解决 重试、重入、超时刷新(看门狗)机制

2.并发模拟测试jmeter

创建好1000个token(用户),放到txt文件。

在jmeter里指定该文件作为token来源,就能模拟1000个用户

因为之前每一步是串行操作的,其中有大量的数据库操作会很影响效率,所以把资格判断和下单业务分离开。 

实战篇-23.秒杀优化-基于Redis完成秒杀资格判断_哔哩哔哩_bilibili

3.优化后流程

4.新增优惠券

调用crud

5.基于Lua脚本,判断秒杀库存、一人一单,决定用户是否抢购成功

新lua脚本

6.如果抢购成功,将优惠券id和用户id封装后存入阻塞队列

因为流程改了,所以原来很多java业务转到lua脚本里去了,需要改造代码。

大致流程

具体操作

6.1阻塞队列

没有元素的时候取对象会阻塞,直到有新内容进来。

6.2开启异步下单线程(线程池)

 7.新流程

        1.先判断资格,有资格就创建订单对象(但没有下单到数据库)把订单加到阻塞队列,否则返回错误。这里用户已经得到结果了,理论上用户知道自己能不能下单。

        2.然后执行异步下单,类初始化执行线程池。线程池里的线程不断从阻塞队列取出需要下单的订单信息,然后去进行下单数据库操作。 

1)阻塞队列在jvm里,内存有限,订单多了容易溢出

2)如果订单加入阻塞队列,但是服务宕机了,订单会丢失

这里使用的阻塞队列很简单,容易出现很多问题,所以后面引入消息队列。

猜你喜欢

转载自blog.csdn.net/m0_50973548/article/details/135043870