RabbitMq死信队列(详解)

news/2024/12/1 5:39:45/

死信队列的概念


死信(dead message)简单理解就是因为种种原因,无法被消费的信息,就是死信。

有死信,自然就有死信队列。当消息在⼀个队列中变成死信之后,它能被重新被发送到另⼀个交换器中,这个交换器就是DLX( Dead Letter Exchange ),绑定DLX的队列,就称为死信队列(Dead Letter Queue,简称DLQ)。

如图所示工作机制:

消息变成死信⼀般是由于以下几种情况:

1. 消息被拒绝( Basic.Reject/Basic.Nack ),并且设置 requeue 参数为false。

2. 消息过期。

3. 队列达到最大长度。

4. 消息发生异常。


代码案例


声明队列和交换机

包含两部分:

• 声明正常的队列和正常的交换机

• 声明死信队列和死信交换机

死信交换机和死信队列和普通的交换机,队列没有区别。

如代码:

//常量类//死信队列 public static final String DLX_EXCHANGE_NAME = "dlx_exchange";public static final String DLX_QUEUE = "dlx_queue";//普通队列public static final String NORMAL_EXCHANGE_NAME = "normal_exchange";public static final String NORMAL_QUEUE = "normal_queue";
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import rabbitmq.Constant;/*** 死信队列相关配置 */@Configurationpublic class DLXConfig {//死信交换机 @Bean("dlxExchange")public Exchange dlxExchange(){return ExchangeBuilder.topicExchange(Constant.DLX_EXCHANGE_NAME).durable(true).build();}//2. 死信队列 @Bean("dlxQueue")public Queue dlxQueue() {return QueueBuilder.durable(Constant.DLX_QUEUE).build();}//3. 死信队列和交换机绑定 Binding @Bean("dlxBinding")public Binding dlxBinding(@Qualifier("dlxExchange") Exchange exchange, 
@Qualifier("dlxQueue") Queue queue) {return BindingBuilder.bind(queue).to(exchange).with("dlx").noargs();
}//正常交换机 @Bean("normalExchange")public Exchange normalExchange(){return ExchangeBuilder.topicExchange(Constant.NORMAL_EXCHANGE_NAME).durable(true).build();}//正常队列 @Bean("normalQueue")public Queue normalQueue() {return QueueBuilder.durable(Constant.NORMAL_QUEUE).build();}//正常队列和交换机绑定 Binding @Bean("normalBinding")public Binding normalBinding(@Qualifier("normalExchange") Exchange exchange, @Qualifier("normalQueue") Queue queue) {return BindingBuilder.bind(queue).to(exchange).with("normal").noargs();}
}

正常队列绑定死信交换机

当这个队列中存在死信时,RabbitMQ会自动的把这个消息重新发布到设置的DLX上,进而被路由到另一个队列,即死信队列。可以监听这个死信队列中的消息以进行相应的处理。

如代码:

@Bean("normalQueue")
public Queue normalQueue() {return QueueBuilder.durable(Constant.NORMAL_QUEUE).deadLetterExchange(Constant.DLX_EXCHANGE_NAME).deadLetterRoutingKey("dlx").build();
}

制造产生死信队列的条件

如代码:

@Bean("normalQueue")
public Queue normalQueue() {return QueueBuilder.durable(Constant.NORMAL_QUEUE).deadLetterExchange(Constant.DLX_EXCHANGE_NAME).deadLetterRoutingKey("dlx").ttl(10*1000)  //消息过期时间.maxLength(10L)  //队列的长度.build();
}

发送消息

如代码:

@RequestMapping("/dlx")public void dlx() {//测试过期时间, 当时间达到TTL, 消息⾃动进⼊到死信队列 rabbitTemplate.convertAndSend(Constant.NORMAL_EXCHANGE_NAME, "normal", "dlx test...");
}

项目启动后,如图:

队列Features说明:

D:durable的缩写,设置持久化

TTL:Time to Live,队列设置了TTL

Lim:队列设置了长度(x-max-length)

DLX:队列设置了死信交换机(x-dead-letter-exchange)

DLK:队列设置了死信RoutingKey(x-dead-letter-routing-key)


发送后消息进入正常的队列。

如图:

10秒后,消息过期,消息进入死信队列。

如图:

当我们发送的消息,10条往上后,溢出的也会进入死信队列。


常见面试题


1. 死信队列的概念死信(Dead Letter)是消息队列中的⼀种特殊消息,它指的是那些无法被正常消费或处理的消息。在消息队列系统中,如RabbitMQ,死信队列用于存储这些死信消息。

2. 死信的来源:

(1)消息过期:消息在队列中存活的时间超过了设定的TTL。

(2)消息被拒绝:消费者在处理消息时,可能因为消息内容错误,处理逻辑异常等原因拒绝处理该消息。如果拒绝时指定不重新入队(requeue=false),消息也会成为死信。

(3)队列满了:当队列达到最大长度,无法再容纳新的消息时,新来的消息会被处理为死信。

3. 死信队列的应用场景对于RabbitMQ来说,死信队列是⼀个非常有用的特性。它可以处理异常情况下,消息不能够被消费者正确消费而被置入死信队列中的情况,应用程序可以通过消费这个死信队列中的内容来分析当时所遇到的异常情况,进而可以改善和优化系统。

比如:用户支付订单之后,支付系统会给订单系统返回当前订单的支付状态。


http://www.ppmy.cn/news/1551401.html

相关文章

HarmonyOS Next 模拟器安装与探索

HarmonyOS 5 也发布了有一段时间了,不知道大家实际使用的时候有没有发现一些惊喜。当然随着HarmonyOS 5的更新也带来了很多新特性,尤其是 HarmonyOS Next 模拟器。今天,我们就来探索一下这个模拟器,看看它能给我们的开发过程带来什…

PaddleOCR:一款高性能的OCR工具介绍

一、引言 随着人工智能技术的不断发展,光学字符识别(OCR)技术在各行各业得到了广泛应用。OCR技术能够将图片、扫描件等非结构化数据中的文字信息提取出来,转换为可编辑的文本格式。在我国,百度开源了一款优秀的OCR工具…

力扣刷题TOP101:8.BM10 两个链表的第一个公共结点

目录: 目的 思路 复杂度 记忆秘诀 python代码 目的 两个无环的单向链表,它们的第一个公共结点{{6,7}。 思路 这个任务是找到两个链表的第一个公共结点。可以看作两个心机boy偷偷补课翻车事件。平时嘴上说自己在家玩游戏,实际上背地里都偷…

浅谈C#库之Memcached

一、Memcached库介绍 Memcached是一个开源的高性能分布式内存缓存系统,它通过将数据存储在内存中来加速动态Web应用。以下是Memcached的一些关键特点: 1、高性能:Memcached使用内存进行数据存储,访问速度极快。 2、分布式&…

[毕业设计]最全计算机专业毕业设计选题推荐汇总(源码+论文)

💗博主介绍:✌全网粉丝10W,CSDN全栈领域优质创作者,博客之星、掘金/华为云/阿里云等平台优质作者。大学毕业那年,曾经有幸协助指导老师做过毕业设计课题分类、论文初选(查看论文的格式)、代码刻录等打杂的事…

JVM_栈详解一

1、栈的存储单位 **栈中存储什么?**, 每个线程都有自己的栈,栈中的数据都是以栈帧(Stack Frame)的格式存在。在这个线程上正在执行的每个方法都各自对应一个栈帧(Stack Frame)。 栈帧是一个内存…

存储过程与自然语言处理逻辑的不同与结合

在现代软件开发中,存储过程与自然语言处理(NLP)逻辑都发挥着重要作用。存储过程是一种在数据库内部运行的预编译程序,通常用于处理与数据相关的任务,例如插入、更新、删除数据以及复杂的查询操作。而自然语言处理&…

C++趣味编程:基于树莓派Pico的模拟沙漏-倾斜开关与LED的互动实现

沙漏,作为一种古老的计时工具,利用重力让沙子通过狭小通道,形成了计时效果。在现代,我们可以通过电子元件模拟沙漏的工作原理。本项目利用树莓派Pico、倾斜开关和LED,实现了一个电子沙漏。以下是项目的详细技术解析与C++代码实现。 一、项目概述 1. 项目目标 通过倾斜开关…