RabbitMQ死信交换机、TTL及延迟队列

一,死信交换机

1,什么是死信交换机

了解死信交换机之前我们先来了解一下什么是死信,当一个队列满足下面的三种情况的时候我们一般称为死信(dead letter):

  • 消费者使用basic.reject或 basic.nack声明消费失败,并且消息的requeue参数设置为false(当消费者未成功处理完消息的时候会给与其绑定的队列返回nack,此时就需要将消息重新入队requeue,如果将requeue参数设置成false消息就会变成死信了);
  • 消息已经过期了,过期的消息没有消费者进行消费就会变成死信;
  • 所需要投递的队列已经满了,最早的消息就会变成死信。

队列中的死信需要将消息转发给另一个交换机,此时整个交换机就被称为死信交换机,死信就可以往整个交换机里进行投递了;我们知道交换机不具备存储消息的能力,所以也需要一个死信队列与其进行绑定。

2,死信交换机投递的流程图

 

二,TTL

1,什么是TTL

TTL,也就是Time-To-Live。如果一个队列中的消息TTL结束仍未消费,则会变为死信,ttl超时分为两种情况:

  • 消息所在的队列设置了存活时间;
  • 消息本身设置了存活时间。

注意:这里是假定没有消费者绑定ttl队列,这样投递到ttl队列中的消息没有消费者进行消费,消息一定会超时,这样就可以将死信成功投递到死信交换机中了!

2,利用TTL模拟消息超时被投递到死信交换机中

1. 演示给队列设置超时时间的情况

1.1 在config包下定义TTLMessageConfig配置ttl交换机和ttl队列的信息,并将队列的超时时间设置为10s

@Configuration
public class TTLMessageConfig {@Beanpublic DirectExchange ttlDirectExchange(){return new DirectExchange("ttl.direct");}@Beanpublic Queue ttlQueue(){return QueueBuilder.durable("ttl.queue").ttl(10000)//设置队列的超时时间是10s.deadLetterExchange("dl.direct").deadLetterRoutingKey("dl").build();}@Beanpublic Binding ttlBinding(){return BindingBuilder.bind(ttlQueue()).to(ttlDirectExchange()).with("ttl");}
}

1.2 利用注解的方式将ttl队列和死信交换机进行绑定并配置相关路由参数

@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "dl.queue", durable = "true"),exchange = @Exchange(name = "dl.direct"),//默认交换机的类型为direct且为持久化的key = "dl"))public void listenDlQueue(String msg) {log.info("消费者接收到了dl.queue的延迟消息" + msg);}

1.3 定义一个测试类进行消息发送观察消息发送成功和被处理的时间间隔是否是10s

@Testpublic void testTTLMessage() {// 1.准备消息Message message = MessageBuilder.withBody("hello, ttl messsage".getBytes(StandardCharsets.UTF_8)).setDeliveryMode(MessageDeliveryMode.PERSISTENT).build();// 2.发送消息rabbitTemplate.convertAndSend("ttl.direct", "ttl", message);// 3.记录日志log.info("消息已经成功发送!");}

 2. 演示给消息设置超时时间的情况

给消息设置超时的场景只需要在消息发送的时候给消息设置上setExpiration参数即可:

@Testpublic void testTTLMessage() {// 1.准备消息Message message = MessageBuilder.withBody("hello, ttl messsage".getBytes(StandardCharsets.UTF_8)).setDeliveryMode(MessageDeliveryMode.PERSISTENT).setExpiration("5000")//给消息设置超时时间.build();// 2.发送消息rabbitTemplate.convertAndSend("ttl.direct", "ttl", message);// 3.记录日志log.info("消息已经成功发送!");}

总结:

  • 给队列设置ttl属性,进入队列后超过ttl时间的消息变为死信;
  • 给消息设置ttl属性,队列接收到消息超过ttl时间后变为死信;
  • 两者共存时,以时间短的ttl为准。

三,延迟队列

1,什么是延迟队列

利用TTL结合死信交换机,我们实现了消息发出后,消费者延迟收到消息的效果。这种消息模式就称为延迟队列(Delay Queue)模式;在idea中可以使用延迟插件来对延迟队列进行操作(自行下载)。

2,延迟队列使用场景

延迟队列的使用场景包括:

  • 延迟发送短信 用户下单,如果用户在15 分钟内未支付,则自动取消;
  • 预约工作会议,20分钟后自动通知所有参会人员。

3,延迟队列的设计及使用

DelayExchange的本质还是官方的三种交换机,只是添加了延迟功能。因此使用时只需要声明一个交换机,交换机的类型可以是任意类型,然后设定delayed属性为true即可。

3.1 基于注解的方式声明一个延迟交换机

@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "delay.queue", durable = "true"),exchange = @Exchange(name = "delay.direct", delayed = "true"),//添加delayed属性            表明是一个延迟交换机key = "delay"))public void listenDelayExchange(String msg) {log.info("消费者接收到了delay.queue的延迟消息");}

3.2 向delay为true的交换机中发送消息,一定要给消息添加一个header:x-delay,值为延迟的时间,单位为毫秒

@Testpublic void testSendDelayMessage() throws InterruptedException {// 1.准备消息Message message = MessageBuilder.withBody("hello, ttl messsage".getBytes(StandardCharsets.UTF_8)).setDeliveryMode(MessageDeliveryMode.PERSISTENT).setHeader("x-delay", 5000)//加上header属性.build();// 2.准备CorrelationDataCorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());// 3.发送消息rabbitTemplate.convertAndSend("delay.direct", "delay", message, correlationData);log.info("发送消息成功");}

延迟队列插件使用步骤:

声明一个交换机,添加delayed属性为true;

发送消息时,添加x-delay头,值为超时时间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/27632.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

消息队列——spring和springboot整合rabbitmq

目录 spring整合rabbitmq——生产者 rabbitmq配置文件信息 倒入生产者工程的相关代码 简单工作模式 spring整合rabbitmq——消费者 spring整合rabbitmq——配置详解 SpringBoot整合RabbitMQ——生产者 SpringBoot整合RabbitMQ——消费者 spring整合rabbitmq——生产者 使…

现代化 Android 开发:Jetpack Compose 最佳实践

作者:古哥E下 如果一直关注 Compose 的发展的话,可以明显感受到 2022 年和 2023 年的 Compose 使用讨论的声音已经完全不一样了, 2022 年还多是观望,2023 年就有很多团队开始采纳 Compose 来进行开发了。不过也有很多同学接触了下 Compose&am…

结合ChatGPT制作PPT

今天看到圈友的一个AI分享,然后自己本身需要做一个分享的PPT。刚好那着帖子实战一下。先说下整体感受。 优点:制作成本确实会比较低,很熟练的话大概就是1分钟一个都有可能。整体流程是先找个第三方PPT制作网站,看下支不支持文本转…

这可能是最简单的Page Object库

做过web自动化测试的同学,对Page object设计模式应该不陌生。 Page object库应该根据以下目标开发: Page object应该易于使用 清晰的结构 PageObjects 对于页面对象 PageModules对于页面内容 只写测试,而不是基础。 在可能的情况下防止样…

使用qemu创建ubuntu-base文件系统,并安装PM相关内核模块

目录 一、配置镜像二、使用qemu模拟nvdimm(安装PM相关内核模块)运行记录 遇到的一些问题1、ext4文件系统损坏问题:系统启动时,遇到ext4的报错信息解决办法:2、内核模块未成功加载3、qemu报错4、主机终端无法正常打开5、…

【深度学习平台推荐】 Kaggle

工欲善其事,必先利其器。在一个优秀的平台上,更利于深度学习的探究。 本文目的是推荐一些深度学习相关的网站。 1 Kaggle Kaggle offers a no-setup, customizable, Jupyter Notebooks environment. Access GPUs at no cost to you and a huge repositor…

GDB调试——学习笔记

文章目录 GDB是什么GDB调试的一般步骤1. 编译生成带源代码信息的可执行文件2. 启动调试3. 进行调试:设置断点、查看变量、寻找BUG4. 退出调试 GDB是什么 GDB就是一个程序代码调试的工具。 GDBGCC开发环境 GDB调试的一般步骤 1. 编译生成带源代码信息的可执行文件…

6.3.5 利用Wireshark进行协议分析(五)----捕获并分析ICMP报文

6.3.5 利用Wireshark进行协议分析(五)----捕获并分析ICMP报文 一、捕获ICMP报文 打开Wireshark,选择网络接口并点击开始按钮。分组列表面板不断刷新抓渠道的数据包,为了过滤出我们所要分析的ICMP报文,我们在过滤框中输…

(学习笔记-连接断开)TCP四次挥手

TCP四次挥手过程 TCP断开连接是通过四次挥手实现的,双方都可以主动断开连接,断开连接后主机中的资源将被释放,四次挥手的过程如下: 客户端打算关闭连接时,会发送一个TCP首部FIN标志位为1的报文,也就是FIN报…

C#中的抽象类(abstract)

C#中的抽象类(abstract)。 1:抽象方法只作声明,而不包含实现,可以看成是没有实现体的虚方法 2:抽象类不能被实例化 3:抽象类可以但不是必须有抽象属性和抽象方法,但是一旦有了抽象方…

OpenCV中reshape()函数详解-改变矩阵的通道数,对矩阵元素进行序列化

文章目录 1、函数原型2、示例3、结论: OpenCV中reshape()函数详解-改变矩阵的通道数,对矩阵元素进行序列化 在opencv中reshape函数,既可以改变矩阵的通道数,又可以对矩阵元素进行序列化 1、函数原型 Mat Mat::reshape(int cn, in…

SQLServer2022安装(Windows),已验证

二、安装可视化工具SSMS 接下来安装可视化工具SSMS,现在新版本默认都是没有可视化界面,需要单独安装 (1)地址:下载 SQL Server Management Studio (SSMS) - SQL Server Management Studio (SSMS) | Microsoft Learn…