相关知识
什么是延迟队列
队列中的消息在等待指定时间后,消费者才能够进行消费。
应用场景
商城系统,下单后半个小时未付款,自动取消订单
实现方式
RabbitMQ 本身没有直接支持延迟队列功能,但是通过控制消息的生存时间及死信队列,可以模拟出延迟队列的效果。
RabbitMQ 控制消息的生存时间有两种方法:
- 设置队列属性(x-message-ttl),队列中所有消息都有相同的过期时间
- 设置消息属性(expiration),拥有单独的过期时间
关于死信队列可以参考 https://gitee.com/gongm_24/spring-boot-tutorial/tree/master/chapter18
目标
整合 Spring boot 提供的 spring-boot-starter-amqp,实现延迟队列
操作步骤
添加依赖
添加后的整体依赖如下
![4b08dee3131f2f89f32c253d47f1567e.png](https://i-blog.csdnimg.cn/blog_migrate/14909b4e25410dd0ecb88b8a5cf4915a.jpeg)
定义队列
定义一个测试队列 TestDeadQueue,并为该队列配置死信队列,配置的方法就是在声明队列的时候,添加参数 x-dead-letter-exchange 及 x-dead-letter-routing-key,其实就是在消费失败时,将消息使用该 exchange 及 routing 发送至指定队列
![a68c18aa3fd9581261a27c4d7c195925.png](https://i-blog.csdnimg.cn/blog_migrate/decde087431609855c853db5d0342175.jpeg)
消息接收方
![94b0f854f0946c6765b68cd181b394e8.png](https://i-blog.csdnimg.cn/blog_migrate/15af91faa0cde8cb890bf4b2f7b69d7f.jpeg)
测试代码
![1ff632561ff7ddb63851e34e53809a0e.png](https://i-blog.csdnimg.cn/blog_migrate/6800a27e56822a841f053b6c14348e1a.jpeg)
息重试
使用延时消息我们还可以实现一种业务场景:延迟的消息重试。有些时候我们可能以为一些原因,导致消息在某一时段处理的失败,但是假如马上进行重试可能会再次失败,我们希望稍后对其进行处理且设置一个可控的重试次数。此时我们可以在延迟消息中进行修改来实现消息重试。
重试的流程
![0ef42956fce45836b3229a13f7b9f999.png](https://i-blog.csdnimg.cn/blog_migrate/6432a815d45e64dcc348e1723f71964c.jpeg)
根据上面的设计,我们需要三个消息队列workQueue业务队列、retryQueue重试队列、failedQueue失败队列。
配置exchange和queue
workQueue
业务处理所订阅的内容,普通队列
![5db77ba5874d2d5c83edd249b1a2256c.png](https://i-blog.csdnimg.cn/blog_migrate/5509522c628812470b1258458adf3603.jpeg)
retryQueue
延时队列,其配置了死信相关参数,其死信队列为workqueue
![53a688c63557b485f4061f32b6473051.png](https://i-blog.csdnimg.cn/blog_migrate/df35555bcf91e4945f08eb09577c1bd6.jpeg)
failedQueue
重试次数超过上限后的消息处理队列,没有额外处理
![710f2d1c850876eb698c940f357c3596.png](https://i-blog.csdnimg.cn/blog_migrate/aab8bb69432c1c45e764b55555e5eef0.jpeg)
配置消息发送者
![769154e55b8a95a4ba26ede8c2362cf3.png](https://i-blog.csdnimg.cn/blog_migrate/340f83bab243c87fd413856275cdb800.jpeg)
配置消息监听者
在对work_queue的消息订阅中,模拟了业务逻辑,进行重试或者转发至失败队列
![25baa3b56da0fcd979094243fa645b06.png](https://i-blog.csdnimg.cn/blog_migrate/9fedc6fbac5122c7e1324bdfb4edfb48.jpeg)
失败队列的订阅处理中一般会进行数据的持久化,以方便后续人工介入进行业务处理
![50a2036634a19300246f86c454dc8016.png](https://i-blog.csdnimg.cn/blog_migrate/969a45511cc007f586492cebe25a0997.jpeg)