MQ消息队列+Lua 脚本实现异步处理下单流程,将同步下单改为异步下单

回顾一下下单流程

用户发起请求

会先请求Nginx,Nginx反向代理到Tomcat,而Tomcat中的程序,会进行串行工作,

分为以下几个操作:

1 查询优惠券

2 判断秒杀库存是否足够

3 查询订单

4 校验是否是一人一单

5 扣减库存

6 创建订单

像什么一人一单,扣减库存这些地方都是要操作数据库的,所以时间会消耗比较多,效率比较低,就是说 ,他是一个串行执行的,所以就需要异步执行操作

优化方案:

我们将耗时较短的逻辑判断放到Redis中,例如:库存是否充足,是否一人一单这样的操作,只要满足这两条操作,那我们一定是可以下单成功的

其次不用等数据真的写进数据库,直接告诉用户我们下单成功就好了,后续的操作呢,后台直接再开一个线程,后台线程再去慢慢执行队列里的消息,这样就可以很快的完成下单任务了,就是先不管有没有真正的下单成功,只要点了下单优惠券就告诉用户下单成功就好了,后续的操作有点慢,得后台的线程再去慢慢的执行队列里的消息

但是存在一个问题就是:有可能已经告诉用户下单成功了,但后边出现了的问题导致其实并没有真正下单成功,那这张优惠券就用不了

这其中存在两个难点:

1 怎么在Redis中快速校验是否一人一单,还有库存判断

2 校验一人一单和将下单数据写入数据库,这是两个线程,我们怎么知道下单是否完成

整体思路:

当用户下单之后,判断库存是否充足,只需要取Redis中根据key找对应的value是否大于0即可,如果不充足,则直接结束。如果充足,则在Redis中判断用户是否可以下单,怎么判断呢?

用set集合,用户一旦下单就将用户id(userId)存入到集合当中,诶当下一次用户下单的时候,就判断一下userId是否在集合里面,如果set集合里面没有该用户的下单数据,就可以下单,如果里面有用户的userId,那就不能下单了,并将userId和优惠券存入到Redis当中,并且返回0,整个过程保证原子性的(也就是没有其他线程插入),所以需要用Lua来操作

同时由于我们需要在Redis中查询优惠券信息,所以在我们新增秒杀优惠券的同时,需要将优惠券信息保存到Redis中

看下图Lua脚本:

相关推荐
兩尛2 分钟前
C++多线程编程
开发语言·jvm·c++
weixin_4280053016 分钟前
C#调用 AI学习从0开始-第1阶段(基础与工具)-第4天CoT思维链学习
开发语言·学习·ai·c#·cot
砍材农夫17 分钟前
物联网 基于netty构建mqtt服务demo演示
开发语言·物联网·php
JAVA面经实录91720 分钟前
Java 并发工具类
java·大数据·开发语言
吃好睡好便好21 分钟前
在Matlab中绘制变半径柱面图
开发语言·人工智能·学习·算法·matlab
驭渊的小故事21 分钟前
Java数据结构集合框架(顺序表(ArrayList)的详细解析)(两千字详细解析)
java·开发语言
hanbr22 分钟前
Qt:事件处理与绘图详解
开发语言·数据库·qt
cen__y27 分钟前
Linux知识点复习总结(2)
linux·运维·服务器·c语言·开发语言
方便面不加香菜27 分钟前
C++ 日期类的实现
开发语言·c++
雁迟30 分钟前
第五章:条件判断与分支语句
开发语言·r语言