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.mzph.cn/news/1492.shtml

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

相关文章

petalinux 无法通过SDK进行TCF调试

IP地址设置没问题 但是无法进行DEBUG 原因是没有开启debug模式,做下图设置重新编译程序生成BOOT.bin即可

追踪 Kubernetes 中的 DNS 查询

在过去的文章中,我们曾 追踪过 Kubernetes 中的网络数据包,这篇文章将追踪 Kubernetes 中的 DNS 查询。 让我们以在 Pod 中解析 Service 完全限定域名(FQDN) foo.bar.svc.cluster.local 为例。 在开始之前,先回顾下 …

微信小程序的目录解析--【浅入深出系列001外篇】

浅入深出系列总目录在000集 如何0元学微信小程序–【浅入深出系列000】 文章目录 本系列校训学习资源的选择先说总目录经常碰到的文件(目录)最最常见的目录pages次最常用的就是images 目录 操作起来真正的操作 配套资源 本系列校训 用免费公开视频,卷…

串口wifi6+蓝牙二合一系列模块选型参考和外围电路参考设计-WG236/WG237

针对物联网数据传输,智能控制等应用场景研发推出的高集成小尺寸串口WiFi串口蓝牙的二合一组合模块。WiFi符合802.11a/b/g/n无线标准,蓝牙支持低功耗蓝牙V4.2/V5.0 BLE/V2.1和EDR,WiFi部分的接口是UART,蓝牙部分是UART/PCM 接口。模…

3Ds max图文教程:高精度篮球3D建模

推荐: NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 第 1 步。使用以下设置在顶部视口上创建球体: 第 2 步。将球体转换为可编辑的多边形: 第 3 步。转到 Edge 子对象级别并剪切以下边缘: 第 4 步。选择以下边,然…

什么是 Elasticsearch 索引?

作者:David Brimley 索引这个术语在科技界已经被用满了。 如果你问大多数开发人员什么是索引,他们可能会告诉你索引通常指的是关系数据库 (RDBMS) 中与表关联的数据结构,它提高了数据检索操作的速度。 但什么是 Elasticsearch 索引&#xff…

Stable Diffusion配置要求,显卡推荐

Stable Diffusion 是一款流行的人工智能图像生成器,您可以在自己的 PC 上运行。但是运行Stable Diffusion的最低规格是多少,哪些组件最重要? Stable Diffusion需要什么 PC 硬件? Stable Diffusion最关键的一个组件是显卡 (GPU)。…

基于scrcpy的Android群控项目重构,获取Android屏幕元素信息并编写自动化事件

系列文章目录 基于scrcpy的远程调试方案 基于scrcpy的Android群控项目重构 基于scrcpy的Android群控项目重构 进阶版 基于scrcpy的Android群控项目重构,获取Android屏幕元素信息并编写自动化事件(视频) 基于scrcpy的Android群控项目重构…

全国节能宣传周丨物通博联智慧能源解决方案助力节能降碳

今年7月10日至16日,为全国第33个节能宣传周。今年全国节能宣传周活动主题是“节能降碳,你我同行”。 全国节能宣传周活动是在1990年国务院第六次节能办公会议上确定的活动周,开展该活动是实施全面节约战略、开展节能降碳宣传教育、推动形成绿…

Vue3组件间的通信方式

目录 1.props父向子组件通信 2.自定义事件 子向父组件通信 3.全局事件总线 4.v-model组件通信(父子组件数据同步) 绑定单个数据同步 绑定多个数据同步 5.useAttrs组件通信 6.ref与$parent ref获取子组件实例对象 $parent获取父组件实例对象 7.p…

postgresql内核分析 spinlock与lwlock原理与实现机制

​专栏内容: postgresql内核源码分析 手写数据库toadb 并发编程 个人主页:我的主页 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物. 概述 在postgresql 中,有大量的并发同步&#xff0…

260道网络安全工程师面试题汇总(附答题解析+配套资料)

由于我之前写了不少网络安全技术相关的文章和回答,不少读者朋友知道我是从事网络安全相关的工作,于是经常有人私信问我: 我刚入门网络安全,该怎么学? 想找网络安全工作,应该要怎么进行技术面试准备&…

Java设计模式-责任链(Chain of Responsibility)模式

介绍 Java责任链(Chain of Responsibility)设计模式是指很多处理对象构成一个链,链中前一个对象指向后一个对象。请求在链中传递,一个请求可以被一个或者多个对象处理。调用方(即客户端)不知道请求会被链中…

【C++】C++11 (3): lambda表达式和包装器

一、lambda表达式 C98中的一个例子 在C98中&#xff0c;如果想要对一个数据集合中的元素进行排序&#xff0c;可以使用std::sort方法。 #include <algorithm> #include <functional> int main() {int a[] { 4,1,8,5,3,7,0,9,2,6 };// 默认按照小于比较&#xff…

JS、Vue鼠标拖拽

JS代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevic…

使用Linux Deploy搭建服务器(五)Linux Deploy添加自启动(亲测可用)linuxdeploy自动化配置

添加开机自动任务,可以省去开机后手动输入初始化命令的操作 一、方式1 run-parts方式,也就是rc.local的方式(这种方式有时候不生效,按照4中的配置就好了) 1、Linux Deploy配置 1.点击右下角的设置图标进入设置界面 2.划到“初始化”那块,“启用”打上勾 选项“run-p…

文件包含漏洞

一、什么是文件包含漏洞 1.文件包含漏洞概述 和SQL注入等攻击方式一样&#xff0c;文件包含漏洞也是一种注入型漏洞&#xff0c;其本质就是输入一段用户能够控制的脚本或者代码&#xff0c;并让服务端执行。 什么叫包含呢&#xff1f;以PHP为例&#xff0c;我们常常把可重复使…

基于GIS的生态敏感性评价与产业路径选择研究:以江西省吉安市为例

导读: 确立绿水青山就是金山银山的理念,建立生态经济体系,是新时代生态环境保护与经济发展的协调之道。对产业规划而言,与生态同行,构建绿色产业体系,是推动地区高质量发展的根本要求。鉴于此,文章从实证角度出发,以江西省吉安市为研究对象,采用生态敏感性评价方法,选…

【Python基础】- break和continue语句

在Python中&#xff0c;break和continue是用于控制循环语句的特殊关键字。 break语句用于跳出当前的循环&#xff08;for循环或while循环&#xff09;&#xff0c;并继续执行紧接着的循环外的代码。它通常用于满足某个条件时提前结束循环。例如&#xff0c;考虑以下示例&#…

RabbitMQ 同样的操作一次成功一次失败

RabbitMQ 是一个功能强大的消息队列系统&#xff0c;广泛应用于分布式系统中。然而&#xff0c;我遇到这样的情况&#xff1a;执行同样的操作&#xff0c;一次成功&#xff0c;一次失败。在本篇博文中&#xff0c;我将探讨这个问题的原因&#xff0c;并提供解决方法。 我是在表…