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++·算法
echoarts2 天前
Rayon Rust中的数据并行库入门教程
开发语言·其他·算法·rust
Aomnitrix2 天前
知识管理新范式——cpolar+Wiki.js打造企业级分布式知识库
开发语言·javascript·分布式
每天回答3个问题2 天前
UE5C++编译遇到MSB3073
开发语言·c++·ue5
伍哥的传说2 天前
Vite Plugin PWA – 零配置构建现代渐进式Web应用
开发语言·前端·javascript·web app·pwa·service worker·workbox
小莞尔2 天前
【51单片机】【protues仿真】 基于51单片机八路抢答器系统
c语言·开发语言·单片机·嵌入式硬件·51单片机
我是菜鸟0713号2 天前
Qt 中 OPC UA 通讯实战
开发语言·qt
JCBP_2 天前
QT(4)
开发语言·汇编·c++·qt·算法
Brookty2 天前
【JavaEE】线程安全-内存可见性、指令全排序
java·开发语言·后端·java-ee·线程安全·内存可见性·指令重排序
百锦再2 天前
[特殊字符] Python在CentOS系统执行深度指南
开发语言·python·plotly·django·centos·virtualenv·pygame