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脚本:

相关推荐
布吉岛的石头9 小时前
Java 程序员第 50 阶段3:数据工程:预训练语料清洗与去重
java·开发语言·人工智能·深度学习·transformer
benchmark_cc9 小时前
QuantDash 安装成功后,如何验证 Python 环境可以正常导入 SDK?
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
学逆向的9 小时前
C 内存属性
c语言·开发语言·算法·网络安全
HAPPY酷11 小时前
C++ 自定义内存池优化点云处理:从裸指针到 RAII 自动回收
开发语言·c++
梦帮科技11 小时前
量子纠缠网络与量子隐形传态攻防:量子中继器信道串扰、纠缠态保真度降解与量子路由劫持
开发语言·网络·人工智能·算法·自动化·php
老王IT11 小时前
C语言语法基础语法介绍
c语言·开发语言·算法
code2cat12 小时前
Java高级篇之JDBC:连接数据库,完成查询、更新与事务
java·开发语言·数据库
hzxxxz12 小时前
PHP引擎两个高危漏洞复盘:计数顺序与旧地址缺陷的机理与处置清单
开发语言·php
马立杰12 小时前
PHP 未授权 RCE 应急响应:CVE-2026-109618 CVE-2026-109619 排查与加固实战
android·开发语言·php