RabbitMQ(死信队列)

一、本文抒写背景

前面我也在延迟队列篇章提到过死信队列,也提到过一些应用场景!

今天呢,这篇文章,主要就是实战一个业务场景的小Demo流程,哈哈,那就是延迟关闭订单。

二、开始啦!let'go!

首先我来讲解下,这个场景非常常见,尤其是和支付挂钩的业务,必然会有类似的场景。

注:

当然,本文重要的是掌握延迟消息的用法,而不是实现一个真实支付的场景!(因为实现真实支付的场景,涉及

的知识太多啦,考虑的情况太多了,呜呜呜,放过我吧!)

三、来吧!Common On,进入代码实现吧!

本章代码实现的整体思路主要为以下:

  • SpringBoot整合RabbitMQ,利用死信队列实现延迟关闭订单的效果。

1. 死信队列原理

利用RabbitMQ的懒消费机制,当消息超过TTL过期时间未被消费,就会通过死信交换机放入死信

队列中,再专门消费死信队列中的消息,达到延迟处理的效果。

一张图看明白

别说啦,前面本人已经提到过死信交换机啦,这张图的思想,跟死信交换机所画图思想有一定的挂钩哟,有兴趣

可参考下本人死信交换机篇章!

2. 实现案例

本文为了突出核心的逻辑,案例就用伪代码来展示啦,省略一些非必要的东西,这样会显得更清晰直观。

创建订单消息对象

复制代码
// OrderMessage.java
public class OrderMessage {
    private String orderId;

    // 省略getter和setter
}

创建订单服务类,也就是执行关闭订单的一些业务逻辑,比如调微信支付关闭订单操作,或改本地业务状态等。

复制代码
@Service
public class OrderService {

    public void closeOrder(String orderId) {
        // 执行关单操作
        System.out.println("关闭订单:" + orderId);
    }
}

创建延迟队列配置类,这里的核心就是利用了RabbitMQ的消息过期(ttl)特性,以及定义死信交换机 --> 转发的

路由 --> 死信队列。

复制代码
@Configuration
public class DelayQueueConfig {

    // 定义延迟队列名称
    public static final String DELAY_QUEUE_NAME = "delay.queue";
    // 定义死信队列名称
    public static final String DEAD_LETTER_QUEUE_NAME = "dead.letter.queue";
    // 定义延迟时间(单位:毫秒)
    public static final long DELAY_TIME = 5000;

    @Bean
    public Queue delayQueue() {
        Map<String, Object> args = new HashMap<>();
        // `x-dead-letter-exchange`被设置为空字符串,表示将死信消息发送到默认交换机。
        // 如果您想要将死信消息发送到特定的交换机,可以将其设置为相应的交换机名称。
        args.put("x-dead-letter-exchange", "");
        args.put("x-dead-letter-routing-key", DEAD_LETTER_QUEUE_NAME);
        args.put("x-message-ttl", DELAY_TIME);
        return new Queue(DELAY_QUEUE_NAME, true, false, false, args);
    }

    @Bean
    public Queue deadLetterQueue() {
        return new Queue(DEAD_LETTER_QUEUE_NAME);
    }
}

创建消息发送者,用于向延迟队列发送订单消息,发送到指定的交换机和延迟队列。

复制代码
@Component
public class OrderMessageSender {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Value(DelayQueueConfig.DELAY_QUEUE_NAME)
    private String delayQueue;

    public void sendOrderMessage(OrderMessage orderMessage) {
        rabbitTemplate.convertAndSend("", delayQueue, orderMessage);
    }
}

创建消息接收者,也就是监听前面定义的死信队列的消息,消费消息并处理关单逻辑。

复制代码
@Component
public class OrderMessageReceiver {

    @Autowired
    private OrderService orderService;

    @RabbitListener(queues = DelayQueueConfig.DEAD_LETTER_QUEUE_NAME)
    public void processDeadLetterMessage(OrderMessage orderMessage) {
        // 处理关单逻辑
        orderService.closeOrder(orderMessage.getOrderId());
    }
}

四、本文总结

最后,咱们再来回顾总结一下利用死信队列实现延迟关单的流程:

1、订单消息通过OrderMessageSender发送到延迟队列。

2、延迟时间过后,订单消息被投递到死信队列。

3、OrderMessageReceiver监听死信队列,一旦有消息到达,调用OrderService的closeOrder方法执行关单

操作。

这种延迟关单功能还可以用于定时任务、订单超时处理等场景。

相关推荐
Otaku love travel6 分钟前
老系统改造增加初始化,自动化数据源配置(tomcat+jsp+springmvc)
java·tomcat·初始化·动态数据源
DKPT19 分钟前
Java设计模式之行为型模式(责任链模式)介绍与说明
java·笔记·学习·观察者模式·设计模式
L_autinue_Star34 分钟前
手写vector容器:C++模板实战指南(从0到1掌握泛型编程)
java·c语言·开发语言·c++·学习·stl
晨岳1 小时前
CentOS 安装 JDK+ NGINX+ Tomcat + Redis + MySQL搭建项目环境
java·redis·mysql·nginx·centos·tomcat
执笔诉情殇〆1 小时前
前后端分离(java) 和 Nginx在服务器上的完整部署方案(redis、minio)
java·服务器·redis·nginx·minio
YuTaoShao1 小时前
【LeetCode 热题 100】24. 两两交换链表中的节点——(解法一)迭代+哨兵
java·算法·leetcode·链表
程序员的世界你不懂1 小时前
(20)Java+Playwright自动化测试- 操作鼠标拖拽 - 上篇
java·python·计算机外设
AI360labs_atyun2 小时前
Java在AI时代的演进与应用:一个务实的视角
java·开发语言·人工智能·科技·学习·ai
不像程序员的程序媛2 小时前
redis的一些疑问
java·redis·mybatis
知其然亦知其所以然3 小时前
Java 面试高频题:GC 到底回收了什么、怎么回收、啥时候回收?
java·后端·面试