【从零开始学习RabbitMQ | 第三篇】什么是延迟消息

目录

前言:

延迟消息:

延迟消息实现方式:

死信交换机:

延迟消息插件:

1.基于注解的方式

2.基于@Bean的方式

总结:


前言:

在现代软件开发中,异步消息处理已成为构建可扩展、高可用系统的关键组成部分。RabbitMQ,作为一款广泛使用的开源消息代理,提供了强大的消息队列功能,支持多种消息模式,包括发布/订阅、请求/响应以及路由等。然而,除了这些基本功能外,RabbitMQ还提供了一项独特的特性------延迟消息,它允许开发者安排消息在将来的某个时间点被处理。

延迟消息,顾名思义,是指那些在发送后不会立即被消费者接收的消息,而是根据预设的延迟时间后才能被消费。这种特性在许多场景下非常有用,例如定时任务的执行、订单超时处理、批处理作业的调度等。通过延迟消息,我们可以将即时处理的需求转化为按计划执行的任务,从而优化资源使用,提高系统的响应性和吞吐量。

延迟消息:

生产者发送消息的时候指定一个时间,消费者不会立即收到消息,而是在指定的时间之后才收到消息。

我举一个实际应用场景:买车票

订单不代表付款,当我们下单之后,只有付款了我们才会更新库存状态 。在苍穹外卖中,我们采用的是定时任务轮询数据库机制,来取消超时订单。

但是这有一个弊端:对数据库的压力太大了,无论是每隔几秒都是对数据库的一次极致拷打。

在黑马点评中,我们用Redis模拟实现了延迟队列,其实就是用Stream去构造订单,过期之后就去数据库查询订单状态。

而在这种环境下,我们可以用RabbitMQ中的延迟队列,当下单之后,我们把消息发送给MQ,设置延迟时间为30分钟,等30分钟后,Rabbitmq检查订单状态,如果未支付就取消订单。

延迟消息实现方式:

死信交换机:

当队列中的消息满足以下一种情况的时候,就会成为死信:

  • 消费者使用basic.reject 或 basic.nack声明消费失败,并且消息的requeue参数设置为fasle
  • 消息是一个过期消息,超时无人消费
  • 要投递的消息队列满了,最早的消息成为死信

当队列通过dead-letter-exchange 属性指定交换机之后,这个队列中的死信就会投递到这个交换机中,这个交换机成为死信交换机。

这种机制的缺点就是代码实现比较麻烦。所以我们接下来介绍一下延迟消息插件。

延迟消息插件:

延迟消息插件是Rabbitmq官方推出的一个插件,原生支持延迟消息,原理是设计了一个支持延迟消息功能的交换机,当消息投递到交换机的时候可以暂存一段时间,到期之后再投递到队列。

Releases · rabbitmq/rabbitmq-delayed-message-exchange (github.com)https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases在上述网址中下载插件之后,存放到RabbitMQ的插件目录下就可以了。

安装延迟消息插件之后,想要实现延迟消息可以通过两桶途径:

1.基于注解的方式

java 复制代码
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "delay.queue", durable = "true"),
            exchange = @Exchange(value = "delay.direct", delayed = "true"),
            key = "delay"
    ))
    public void listenDelayQueue(String msg) {
        log.info("delay.queue:" + msg);
    }

2.基于@Bean的方式

java 复制代码
@Configuration
public class DirectConfiguration {
 
    @Bean
    public DirectExchange delayExchange() {
        return ExchangeBuilder
                .directExchange("delay.direct")
                .delayed()
                .durable(true)
                .build();
    }
 
    @Bean
    public Queue delayedQueue() {
        return new Queue("delay.queue");
    }
 
    @Bean
    public Binding delayQueueBinding() {
        return BindingBuilder.bind(delayedQueue()).to(delayExchange()).with("delay");
    }
}

总结:

在本文中,我们深入探讨了RabbitMQ中延迟消息的概念、实现方式以及应用场景。延迟消息是RabbitMQ提供的一项强大功能,它允许开发者安排消息在将来的某个特定时间点被处理,这种能力在许多实际应用中非常有用。

首先,我们介绍了延迟消息的基本概念,解释了它与传统即时消息处理的区别。我们了解到,延迟消息可以用于处理那些不需要立即执行的任务,而是可以安排在未来某个时间点执行。

接着,我们详细讨论了RabbitMQ实现延迟消息的几种方法,包括使用死信交换机(DLX)和消息的TTL属性,以及RabbitMQ 3.7版本之后引入的直接支持延迟消息的特性。这些方法各有优势,可以根据不同的业务需求和场景进行选择。

我们还探讨了如何配置和使用延迟消息,包括如何设置消息的延迟时间,以及如何创建和绑定死信交换机和死信队列。通过这些配置,我们可以确保消息在指定的延迟时间后被正确处理。

此外,我们讨论了延迟消息在实际应用中的价值,包括但不限于定时任务调度、订单超时处理、促销活动触发等场景。延迟消息的使用可以显著提高系统的灵活性和响应能力。

如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!

相关推荐
阳光九叶草LXGZXJ33 分钟前
达梦数据库-报错-16-MERGE INTO提示:无效的列名[XX]
linux·运维·数据库·sql·学习
xxwl58538 分钟前
RabbitMQ 学习笔记
笔记·学习·rabbitmq
李日华大战鸡红3 小时前
滑膜观测器(学习记录)
stm32·单片机·学习·matlab·机器人
传奇开心果编程3 小时前
【现代声明式UI学与练】第4课 列表渲染与 key——如何高效渲染列表、key 的作用、列表重排时的状态保持
学习·flutter·react native·ui·swiftui·android jetpack
传奇开心果编程4 小时前
【Compose Multiplatform 跨端开发学与练】第5课 网络与数据层
android·网络·学习·ui·ios·kotlin·composer
yt004yt4 小时前
园区 VOC 绿岛集中治理项目,管网与监测系统设计要点
大数据·学习
一条破秋裤4 小时前
06_从设备读数据_字符设备read_write流程
学习
m4Rk_5 小时前
【论文阅读】Agent 记忆机制(92):EMPO²——让 Memory 从经验复用走向主动探索
论文阅读·人工智能·学习·开源·github
欣欣之王来了6 小时前
前端开发学习路线图:2026年Vue方向最新版
前端·学习·架构·项目·vue3教程
wdfk_prog6 小时前
LWIP教程 00:从网线上的电信号到 lwIP——PHY、MAC、DMA 与 `netif` 的完整边界
运维·网络·笔记·学习·ip