当前位置: 首页 > news >正文

死信队列详解

什么是死信队列?

在消息队列中,执行异步任务时,通常是将消息生产者发布的消息存储在队列中,由消费者从队列中获取并处理这些消息。但是,在某些情况下,消息可能无法正常地被处理和消耗,例如:格式错误、设备故障等,这些未成功处理的消息就被称为“死信”。

为了避免这些未成功处理的消息导致程序异常或对系统造成影响,我们需要使用死信队列(Dead Letter Queue)。当我们设置死信队列后,所有无法成功处理的消息将被捕获并重定向到指定的死信交换机中。消费者可以从该交换机中读取并处理这些“死信”。

死信队列的优点

使用死信队列有以下优点:

  • 提高系统可靠性:避免因未处理的死信而导致程序异常,提高系统的可靠性。
  • 实现延迟消息:可以通过设置TTL时间,将超时未消费的消息转移到死信队列中,实现延迟消息的功能。
  • 防止滥用:当某些生产者恶意发送低质量的消息或进行滥用时,可以通过丢弃或重定向死信消息来防止滥用和恶意攻击。

死信队列的应用场景

死信队列在以下场景下是非常有用的:

  • 消息格式错误:当消息格式错误时,可能会导致消费者无法正确地解析或处理该消息,这个问题通常与生产者的代码有关。为了避免消息失效,并提高系统可靠性,我们可以使用死信队列。
  • 消费者故障:另一个常见的场景是消息处理者无法正确地处理或响应到推入到队列中的消息,例如消费者创建了一个协程并在逻辑执行完成后未正确地关闭该协程。由于该协程始终处于打开状态,它将一直阻止该消费者对其他消息进行正确消费。为了避免这种消息挂起并影响其他消息的正常处理,可以将其加入死信中心。

死信队列的实现方式

下面通过RabbitMQ和Spring Boot,演示如何实现死信队列。

RabbitMQ实现

创建交换机和队列

import pikadef main():credentials = pika.PlainCredentials('guest', 'guest')parameters = pika.ConnectionParameters('localhost', 5672, '/', credentials)# 创建死信交换机dlx_exchnage_name = 'my-dlx-exchange'with pika.BlockingConnection(parameters) as connection:channel = connection.channel()channel.exchange_declare(exchange=dlx_exchnage_name, exchange_type='fanout', durable=True)# 创建死信队列和交换机dead_letter_queue_name = 'dead-letter-queue'with pika.BlockingConnection(parameters) as connection:channel = connection.channel()channel.queue_declare(queue=dead_letter_queue_name, durable=True)channel.queue_bind(queue=dead_letter_queue_name, exchange=dlx_exchnage_name)# 创建消息队列,并将其绑定到死信队列上  queue_name = "job-queue"arguments = {"x-dead-letter-exchange": dlx_exchnage_name} with pika.BlockingConnection(parameters) as connection:channel = connection.channel()channel.queue_declare(queue=queue_name, durable=True,arguments=arguments)channel.queue_bind(exchange='', queue=queue_name, routing_key=queue_name)print("Queue is created")if __name__ == '__main__':main()

以上代码创建了两个队列,一个是my-dlx-exchange,一个是dead-letter-queue。同时创建另外一个名为job-queue的队列,它绑定了dead-letter-exchange这个交换机。

在发送消息时,需要提供一些属性来指定该队列应采取哪些步骤来防止该类丢失的消息。 这里我们可以使用x-dead-letter-exchangex-message-ttl两个特殊属性,告诉RabbitMQ,如果消息在某段时间内无法正确处理,则将其放入死信队列中。

发送和接收消息

import pikadef send_message():credentials = pika.PlainCredentials('guest', 'guest')parameters = pika.ConnectionParameters('localhost', 5672, '/', credentials)connection = pika.BlockingConnection(parameters)channel = connection.channel()# 发送一个消息5秒后过期,并且未被消费端确认queue_name = "job-queue"properties = pika.BasicProperties(delivery_mode=2,expiration="5000")channel.basic_publish(exchange='', routing_key=queue_name, body='Hello World!', properties=properties)channel.close()connection.close()def receive_message():credentials = pika.PlainCredentials('guest', 'guest')parameters = pika.ConnectionParameters('localhost', 5672, '/', credentials)connection = pika.BlockingConnection(parameters)channel = connection.channel()dlx_exchnage_name = 'my-dlx-exchange'def callback(ch, method, properties, body):print("Receivedmessage: %r" % body)ch.basic_ack(delivery_tag=method.delivery_tag)# 消费来自job-queue的消息queue_name = "job-queue"channel.basic_consume(queue_name, callback)channel.start_consuming()if __name__ == '__main__':send_message()receive_message()

以上代码是一个简单的生产者和消费者。send_message()函数发送一个消息,并且未被消费端确认;receive_message()函数从job-queue中接收消息。

Spring Boot实现

在Spring Boot中,我们可以使用RabbitMQ来实现死信队列。

添加依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

配置文件

spring:rabbitmq:host: localhostport: 5672username: guestpassword: guest

创建死信交换机、队列和绑定

@Configuration
public class RabbitConfig {// 死信交换机public static final String DLX_EXCHANGE_NAME = "my-dlx-exchange";// 死信队列public static final String DEAD_LETTER_QUEUE_NAME = "dead-letter-queue";// 业务处理队列public static final String PROCESS_QUEUE_NAME = "process-queue";@Beanpublic TopicExchange dlxExchange() {return new TopicExchange(DLX_EXCHANGE_NAME);}@Beanpublic Queue deadLetterQueue() {return QueueBuilder.durable(DEAD_LETTER_QUEUE_NAME).withArgument("x-dead-letter-exchange", DLX_EXCHANGE_NAME).build();}@Beanpublic Queue processQueue() {return QueueBuilder.durable(PROCESS_QUEUE_NAME).withArgument("x-message-ttl", 5000).withArgument("x-dead-letter-exchange", DLX_EXCHANGE_NAME).build();}@Beanpublic Binding dlxBinding(Queue deadLetterQueue, TopicExchange dlxExchange) {return BindingBuilder.bind(deadLetterQueue).to(dlxExchange).with("#");}}

以上代码创建了my-dlx-exchange死信交换机和dead-letter-queue死信队列。同时创建一个process-queue业务处理队列,该队列设置了消息的生存时间为5s,并在该时间内未被消费者消费,则将该消息转移到死信队列中。

发送和接收消息

@Component
public class MessageSender {@Autowiredprivate RabbitTemplate rabbitTemplate;public void send(String message) {rabbitTemplate.convertAndSend("", RabbitConfig.PROCESS_QUEUE_NAME, message);}}@Component
public class MessageReceiver {@RabbitListener(queues = "process-queue")public void receive(String message) throws Exception {System.out.println("Received message: " + message);Thread.sleep(10000);}}

以上代码是一个简单的生产者和消费者。生产者使用RabbitTemplate来发送消息到process-queue队列中;消费者通过使用注解@RabbitListener监听process-queue队列的消息并进行处理。

结语

通过本篇文章,我们详细介绍了什么是死信队列、死信队列的优点、应用场景以及如何实现死信队列。通过RabbitMQ和Spring Boot的实现方式,不难看出死信队列在项目中的重要性和实际价值。在工程实践中,我们可以根据具体业务需求,结合技术选型,灵活运用死信队列来提高系统的可靠性和稳定性。

相关文章:

死信队列详解

什么是死信队列&#xff1f; 在消息队列中&#xff0c;执行异步任务时&#xff0c;通常是将消息生产者发布的消息存储在队列中&#xff0c;由消费者从队列中获取并处理这些消息。但是&#xff0c;在某些情况下&#xff0c;消息可能无法正常地被处理和消耗&#xff0c;例如&…...

我用ChatGPT写2023高考语文作文(五):北京卷I

2023年 北京卷 I 适用地区&#xff1a;北京 “续航”一词&#xff0c;原指连续航行&#xff0c;今天在使用中被赋予了新的含义&#xff0c;如为青春续航、科技为经济发展续航等。 请以“续航”为题目&#xff0c;写一篇议论文。 要求&#xff1a;论点明确&#xff0c;论据充实&…...

《微服务实战》 第二十八章 分布式锁框架-Redisson

前言 Redisson 在基于 NIO 的 Netty 框架上&#xff0c;充分的利⽤了 Redis 键值数据库提供的⼀系列优势&#xff0c;在Java 实⽤⼯具包中常⽤接⼝的基础上&#xff0c;为使⽤者提供了⼀系列具有分布式特性的常⽤⼯具类。使得原本作为协调单机多线程并发程序的⼯具包获得了协调…...

局部搜索,变邻域搜索算法

目录 局部搜索 02 变邻域搜索算法 局部搜索 1.1 局部搜索是什么玩意儿? 官方一点:局部搜索是解决优化问题的一种启发式算法。对于某些计算起来非常复杂的优化问题,比如各种NP-难问题,要找到最优解需要的时间随问题规模呈指数增长,因此诞生了各种启发式算法来退而求其次…...

软件工程实训——第一天

第一天 前后分离 前端&#xff1a;android 后端&#xff1a;springbootmbatis-plus 高心星 软件工程的思维来开发项目 问题定义 可行性研究 需求分析 概要设计 详细设计 编码 测试 维护 需求分析 1.用户的信息管理 2.新增支出 3.新增收入 4.支出统计 5.收入…...

嵌入式C语言中if/else如何优化详解

观点一&#xff08;灵剑&#xff09;&#xff1a; 前期迭代懒得优化&#xff0c;来一个需求&#xff0c;加一个if&#xff0c;久而久之&#xff0c;就串成了一座金字塔。 当代码已经复杂到难以维护的程度之后&#xff0c;只能狠下心重构优化。那&#xff0c;有什么方案可以优雅…...

【LSTM】读取时间序列数据 | 时间序列数据的小批量划分方法

由于序列数据本质上是连续的&#xff0c;因此我们在处理数据时需要解决这个问题。当序列过长而不能被模型一次性全部处理时&#xff0c;我们希望能拆分这样的序列以便模型方便读取。 Q&#xff1a;怎样随机生成一个具有n个时间步的mini batch的特征和标签&#xff1f; A&…...

K8s in Action 阅读笔记——【12】Securing the Kubernetes API server

K8s in Action 阅读笔记——【12】Securing the Kubernetes API server 12.1 Understanding authentication 在上一章中&#xff0c;我们提到API服务器可以配置一个或多个认证插件&#xff08;授权插件也是同样的情况&#xff09;。当API服务器接收到一个请求时&#xff0c;它…...

爆肝整理,3个月从功能进阶自动化测试,一跃成测试卷王...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 首先先了解自动化…...

人生这场概率游戏,怎么玩

只会标准答案&#xff0c;是不可救药的愚蠢 那么为了便于理解&#xff0c;我用一些典型的案例来讲解&#xff0c;什么是概率游戏&#xff0c;以及这个游戏&#xff0c;应该怎么玩。 比如典型的相亲&#xff0c;婚恋。人生大事&#xff0c;用标准答案来说&#xff0c;你的意中人…...

Redis笔记

缓存过期时间很重要&#xff01;redis是单线程的 对于内存过多的3中方案&#xff1a; 惰性删除&#xff1a; 在定时删除的基础上&#xff0c;对于已经过期了的数据&#xff0c;redis的随机选择算法一直没有选中这个数据&#xff0c;所以导致它就一直没被删除&#xff0c;但是…...

centos 安装supervisor并运行网站

前言 之前一直用宝塔的**进程守护管理器【Supervisor】**来启动一些项目,如ThinkPHP、Hyperf的项目,或laravel的一些命令。如果不用宝塔怎么办呢? 一、简介[supervisor] [Supervisor] 是用Python开发的一个client/server服务,是Linux/Unix系统下的一个进程管理工具,不支…...

Hadoop面试题十道

问题 1&#xff1a;Hadoop是什么&#xff1f; 答案&#xff1a;Hadoop是一个开源的分布式计算框架&#xff0c;用于处理大规模数据集的存储和处理。它基于Google的MapReduce和Google文件系统&#xff08;GFS&#xff09;的思想&#xff0c;旨在解决大数据量的处理和分析问题。…...

使用Docker-Compose对Docker容器集群快速编排

目录 一、Docker-Compose1、Docker-Compose使用场景2、Docker-Compose简介3、Docker-Compose安装部署4、YAML 文件格式及编写注意事项5、Docker Compose配置常用字段6、Docker Compose 常用命令7、Docker Compose 文件结构8、docker Compose撰写nginx 镜像9、docker Compose撰写…...

React-Redux 对Todolist修改

在单独使用redux的时候 需要手动订阅store里面 感觉特别麻烦 不错的是react有一个组件可以帮我们解决这个问题, 那就是react-redux。 react-redux提供了Provider 和 connent给我们使用。 先说一下几个重点知道的知识 Provider 就是用来提供store里面的状态 自动getState()co…...

初识微信小程序

新建小程序 创建一个新的微信小程序项目&#xff1a; 打开微信开发者工具&#xff0c;点击“新建项目”。 在弹出的窗口中&#xff0c;填写小程序的 AppID、项目名称和项目目录等信息。 点击“确定”按钮&#xff0c;等待微信开发者工具自动下载并安装所需的依赖库和框架。 …...

我们该如何入门编程呢

提醒&#xff1a;以下内容仅做参考&#xff0c;可自行发散。在发布作品前&#xff0c;请把不需要的内容删掉。 随着信息技术的快速发展&#xff0c;编程已经成为一个越来越重要的技能。那么&#xff0c;我们该如何入门编程呢&#xff1f;选择编程语言&#xff1a;选择一种编程…...

App 软件开发《判断6》试卷及答案

App 软件开发《判断6》试卷及答案 文章目录 App 软件开发《判断6》试卷及答案判断题&#xff08;对的打“√”&#xff0c;错的打“”&#xff1b;共0分&#xff09;1&#xff0e;”ionic resources --icon"命令用于生成适应不同分辨率的App图标所应用的图片。(✔)2&#…...

MVC工作原理

MVC工作原理 有视图的情况 1.客户端&#xff08;浏览器&#xff09;发起请求&#xff0c;DispatcherServlet拦截请求。 2.DispatcherServlet根据请求信息调用HandlerMapping。HandlerMapping根据uri去匹配查询能处理的Handler&#xff08;也就是我们所说的Controller&#x…...

使用 Redis 统计网站 UV 的方法

使用 Redis 统计网站 UV 的方法(概率算法) 文章目录 前言思路HyperLogLog 使用 Redis 命令操作使用 Java 代码操作 HyperLogLog 实现原理及特点使用 Java 实现 HyperLogLog小结 前言 网站 UV 就是指网站的独立用户访问量Unique Visitor&#xff0c;即相同用户的多次访问需要…...

黑客工具软件大全

黑客工具软件大全100套 给大家准备了全套网络安全梓料&#xff0c;有web安全&#xff0c;还有渗透测试等等内容&#xff0c;还包含电子书、面试题、pdf文档、视频以及相关的网络安全笔记 &#x1f447;&#x1f447;&#x1f447; 《黑客&网络安全入门&进阶学习包》 &a…...

uniapp主题切换功能的第二种实现方式(scss变量+require)

在上一篇 “uniapp主题切换功能的第一种实现方式&#xff08;scss变量vuex&#xff09;” 中介绍了第一种如何切换主题&#xff0c;但我们总结出一些不好的地方&#xff0c;例如扩展性不强&#xff0c;维护起来也困难等等&#xff0c;那么接下我再给大家介绍另外一种切换主题的…...

# 蓝牙音频相关知识

蓝牙音频相关知识 文章目录 蓝牙音频相关知识1 音频源2 蓝牙音频编解码器3 一些标准4 蓝牙音频其他相关知识4.1 蓝牙版本4.2 ANC&#xff08;主动降噪&#xff09;4.3 音响相关参数4.4 音质评价4.5 HI-Fi声音特点4.6 耳机线材4.7 耳机分类4.8 IP防尘防水等级4.9 噪音与量化噪音…...

【AI作画】使用DiffusionBee with stable-diffusion在mac M1平台玩AI作画

DiffusionBee是一个完全免费、离线的工具。它简洁易用&#xff0c;你只需输入一些标签或文本描述&#xff0c;它就能生成艺术图像。 DiffusionBee下载地址 运行DiffusionBee的硬性要求&#xff1a;MacOS系统版本必须在12.3及以上 DBe安装完成后&#xff0c;去C站挑选自己喜欢…...

2 STM32库函数 之 通用同步异步收发器(USART、串口)所有函数的介绍及使用

2 STM32库函数 之 通用同步异步收发器&#xff08;USART、串口&#xff09;所有函数的介绍及使用 前言一、USART固件库函数预览二、USART固件库函数具体介绍2.1 库函数 USART_DeInit2.2 库函数 USART_Init2.2.1 USART_InitTypeDef structure2.2.2 USART_InitTypeDef 成员 USART…...

SpringCloudAlibaba整合Sentinel实现流量控制熔断降级

目录 一、概念 二、整合Sentinel控制台 三、Sentinel规则配置 四、@SentinelResource资源保护注解...

CentOS 7安装 Postgre

零、前置条件 系统CentOS 7&#xff0c;并已联网&#xff0c;已安装gcc或者g编译器&#xff0c;GNU make版本3.80或以上&#xff0c;系统有至少一个除root之外的普通用户user gcc安装-参考链接查看make命令的版本——make --version更新make版本-参考链接postgresql的使用一般…...

rpc 异步非阻塞 io 配置 线程池和队列

相关 雪崩 - 如何重试 - sla和重试风暴的双保证_个人渣记录仅为自己搜索用的博客-CSDN博客 接口耗时公式 耗时 cpu时间 io时间 线程池数量 最佳数目 1s / 平均cpu时间 * 内核数. 最大平均cpu时间 接口耗时- all外部io时间. 结合gc , linux本身其他线程, 只会还少点. …...

【Turfjs的java版本JTS】前面讲了Turfjs可以实现几何计算,空间计算的功能,如果后端要做这项功能也有类似的类库,JTS

JTS Java Topology Suite 几何计算&#xff1a; 1. 前端js就用这个 Turfjs的类库。参考网站&#xff1a; 计算两线段相交点 | Turf.js中文网 2. 后端java语言就可以用 JTS这个类库&#xff0c;参考网站&#xff1a; JTS参考网站&#xff1a; 1. https://github.com/locatio…...

从Window中先多瞥几眼

JavaFx17官方文档中有如下的描述: Window类是一个顶层窗口类,在其中可以承载场景,并与用户交互。窗口可以是Stage、PopupWindow或其他类似的顶层窗口。 JavaFX Stage类是顶级的JavaFX容器。初级阶段由平台搭建。其他Stage对象可以由应用程序构造。 许多Stage属性是只读的…...

国外对网站开发的研究/百度资讯指数

在MYSQL 中格式化输出 date_forma t(date,yyyyMMddHHmmss) Oracle 中格式化输出 to_char(time ,yyyyMMddHHmmss) SQL Server CONVERT(varchar(20),字段,20) 转载于:https://www.cnblogs.com/ITyueguangyang/p/4071746.html...

网站建设策划 流程/在线一键建站系统

Would you like to change the user interface language in any edition of Windows 7 or Vista on your computer? Here’s a free app that can help you do this quickly and easily. 您想在计算机的任何版本的Windows 7或Vista中更改用户界面语言吗&#xff1f; 这是一个…...

太原做网站的鸣蝉公司/网页百度网盘

来源&#xff1a;http://www.open-open.com/news/view/102a2de 特性一&#xff1a;正则表达式 相信大家都会非常喜欢这个特性&#xff0c;无须服务器端的检测&#xff0c;使用浏览器的本地功能就可以帮助你判断电子邮件的格式&#xff0c;URL&#xff0c;或者是电话格式&#x…...

wordpress广告位插件/肇庆seo排名

在创建SpringBoot项目时&#xff0c;勾选Spring Security依赖&#xff0c;会在Maven中导入Spring Security。org.springframework.boot spring-boot-starter-security这个依赖中有一个登陆拦截器&#xff0c;SpringBoot项目访问任意接口(页面)都跳转到login登录页面这是Spring…...

网站建设 小知识/爱网站查询

转自&#xff1a;http://www.pinlue.com/article/2020/09/0413/1211184961256.html...

汕头 做网站/百度官方客服电话

原标题&#xff1a;国科大生物试卷玩诗意走红网络《蛋白质工程原理》试卷节选孤山叶落春梦在&#xff0c;杏花疏影笛横吹。下列哪种氨基酸易在肽链中形成拐角&#xff1a;( )A、缬氨酸 B、酪氨酸 C、脯氨酸 D、苏氨酸 E、色氨酸我自开来我自落&#xff0c;有人没人香四方。唯有…...