本章将通过学习rabbitMQ基础中的延时队列和死信队列,然后写一个demo实现一个小例子,在商城购物时,先下单创建订单记录,然后可以选择进行立即支付或者不支付,若30秒后不支付,则删除订单。下面针对这个例子进行学习。
首先展示一下最终效果,并进行效果讲解,如下所示:
描述:点击购买,创建订单记录,在倒计时内支付成功的话,正常完成购买流程。
描述:点击购买,创建订单记录,在倒计时内未支付成功的话,删除该笔订单。
下面为了满足上述效果,进行实现。
一、分析例子
为了满足上面的效果,可以通过很多方法实现,最简单的就是定时任务,创建一个定时任务,定时去请求数据,查看状态为未支付的订单,并删除。当然还可以通过redis或者其他办法,本章当然是通过RabbitMQ的方式实现,将通过延时队列和死信队列实现,逻辑关系如下:
所以需要创建如下几个东西:
- 延时交换机
- 延时队列
- 延时队列绑定关系
- 死信交换机
- 死信队列
- 死信队列绑定关系
- 消费者端死信队列监听器
- 生产者端创建订单接口(内含发送消息到延时队列)
- 生产者端支付订单接口
分析完毕,下面开整。
建表语句
二、编写前端代码
上面测试效果是随便整的,过于简便,代码我直接贴出来:
用的ajax和bootstrap。
三、整理模块
下面开始本章的核心改造,首先补一下前面章节的坑,建立父子工程时,直接在父工程的maven进行打包会出异常,因为其中含有一个common公共模块,其他服务有使用commo模块的东西,为了避免编译整个父工程时再报错,在功能模块代码的pom文件,增加如下代码:
这样,下次在父工程直接编译就不会再找不到各个模块对commom模块的依赖了。
然后本次测试会涉及到数据库的操作,所以直接引入mybatis-plus,便于操作,关于mybatis-plus的操作,前面springboot整合篇有讲到。
此处再简单讲一下整合mybatis-plus简要步骤:
- 导入依赖到父工程
- 修改provider模块和consumer模块业务模块的配置类yml文件
两个模块的yml配置文件记得都要修改。
- 关于报错,数据库版本问题可能导致依赖版本存在一些不一致,会出现一系列问题,根据报错百度一下即可解决。
四、改造common公共模块
接下来改造common模块,为了方便管理,每个模块公用的东西都放到了common子工程,上一章有将topic主题模式消息队列涉及到的常量放到common的RabbitMQConstant类中,但是本章为了方便看,就直接不将常量信息放到其中。
- 创建实体类
id使用mybatis-plus的UUID雪花算法自动生成。
- 本来想将mapper也放到其中,但是放到其中后,其他模块使用时会导致接口无法访问,问题还未解决。
五、改造provider服务提供方
还是展示一下改造后的provider服务的最终目录结构,如下:
框选部分为新增代码,下面开整。
- 新增mapper类
- 新增订单操作接口
简要描述:
1、创建一个支付接口,一个创建订单接口。
2、创建订单接口:创建订单记录,并发送消息(传订单id)到延时交换机,并将id返回前端方便前端调用支付接口。
3、支付接口:根据订单id,改变订单已支付状态,避免被消息监听器处理。
六、改造consumer服务消费方
接着改造consumer服务,最终目录结构如下:
框选处为新增代码。
- 新增mapper,和生产者服务一样,本来应该可以放到common,但是我还未解决问题,只能先这样处理。
- 新增延时队列和死信队列的配置类TopicDelayConfig。
简要描述:
类似原来的主题模式的常规配置,只不过此处的延时队列创建时有所不同,需要先设置好各个参数再创建,注释有说明,此处为了方便操作,直接使用的路由模式,没有使用主题模式。
- 创建延时交换机
- 创建死信交换机
- 创建延时队列,并设置延时时间以及,成为死信后进入哪一个交换机并设置路由键
- 创建死信队列
- 创建死信队列和死信交换机的绑定关系
- 创建延时队列和延时交换机的绑定关系
3. 新增死信队列监听器
简要描述:
根据从队列接收到的消息处理具体的逻辑,根据订单id查询订单记录,若存在则判断是否已支付,若未支付则删除。
七、演示
演示效果如本章开篇所展示的一致,此处就不展示了,感兴趣的朋友可以尝试一下,over。
——————————————————完毕——————————————————