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

RabbitMQ 高级特性——重试机制

在这里插入图片描述

文章目录

  • 前言
  • 重试机制
    • 配置文件设置
    • 生命交换机、队列和绑定关系
    • 生产者发送消息
    • 消费消息

前言

前面我们学习了 RabbitMQ 保证消息传递可靠性的机制——消息确认、持久化和发送发确认,那么对于消息确认和发送方确认,如果接收方没有收到消息,那么这时该怎么做呢?这就要提到 RabbitMQ 的重试机制了,当发送方发送的消息没有成功到达接收方,那么发送方就会使用重试机制来向接收方重新发送消息,如果接收方因为程序逻辑错误引起的,那么不管发送方重新发送多少次,接收方都不能正确的处理这个消息,那么发送方也不能无休止的向接收方发送消息,当发送的次数超过某个数量的时候,那么这个消息就会被标记为死信,然后被处理掉。那么这篇文章将详细的说明一下 RabbitMQ 的重试机制。

重试机制

RabbitMQ的重试机制是一种强大的功能,它允许在消息处理失败时自动重试,从而提高系统的可靠性和稳定性。

重试机制的触发条件

  1. 消息发送失败:当消息发送到RabbitMQ服务器时,如果因为网络问题、认证失败或其他原因导致发送失败,RabbitMQ会尝试重试发送。
  2. 消息消费失败:当消费者从队列中获取消息并尝试处理时,如果因为某种原因(如业务逻辑错误、系统异常等)导致处理失败,RabbitMQ会根据预设的重试策略进行重试。

我们都知道 Spring AMQP 提供了四种确认策略:NONE、MANUAL、AUTO。当确认策略为 NONE 的时候队列不管这个消息是否被成功处理都会将这个消息从队列中删除,而确认策略为 MANUAL 的时候则更多的靠程序本身处理,那么重试机制更多的使用在确认策略为 AUTO 的情况下。

配置文件设置

spring:rabbitmq:addresses: amqp://admin:admin@x.x.x.x:5672/testlistener:simple:acknowledge-mode: auto # 确认模式retry:enabled: true # 开始重试机制initial-interval: 5000ms # 每次重试的间隔时间max-attempts: 5 # 最大重试次数

生命交换机、队列和绑定关系

public class Constants {public static final String RETRY_EXCHANGE = "retry.exchange";public static final String RETRY_QUEUE = "retry.queue";
}
@Configuration
public class RabbitConfig {@Bean("retryExchange")public DirectExchange retryExchange() {return ExchangeBuilder.directExchange(Constants.RETRY_EXCHANGE).durable(true).build();}@Bean("retryQueue")public Queue retryQueue() {return QueueBuilder.durable(Constants.RETRY_QUEUE).build();}@Bean("retryBinding")public Binding retryBinding(@Qualifier("retryQueue") Queue queue, @Qualifier("retryExchange") DirectExchange exchange) {return BindingBuilder.bind(queue).to(exchange).with("retry");}
}

生产者发送消息

@RequestMapping("/producer")
@RestController
public class ProducerController {@Autowiredprivate RabbitTemplate rabbitTemplate;@RequestMapping("/retry")public String retry() {rabbitTemplate.convertAndSend(Constants.RETRY_EXCHANGE,"retry","rabbitmq retry");return "消息发送成功";}
}

消费消息

@Component
public class RetryListener {@RabbitListener(queues = Constants.RETRY_QUEUE)public void listener(Message message, Channel channel) {System.out.println("接收到消息:" + message + channel);//制造出异常使得消费者不能正常处理消息int ret = 3/0;System.out.println("消息处理成功");}
}

我们先将重试机制的配置给注释掉,然后运行之后会发现消费者会重复读取一条消息并且一直抛异常,这是因为:

由于监听器方法抛出了异常并且没有被捕获,Spring AMQP将不会发送ACK,RabbitMQ将不断重新投递这条消息给消费者,直到它最终被确认、被拒绝(并可能发送到死信队列)或队列被删除。

那么我们配置重试机制的重试次数之后再看看什么效果:

在这里插入图片描述

可以发现,当配置了重试次数之后,包括第一次投递消息,队列一共给消费者发送了五次消息,并且这个五次的消息的 deliveryTag 是一样的,也就说明是队列的重试机制投递的,五次之后队列便不再向该消费者发送该消息,这样就避免了因消费者的程序逻辑问题而导致队列无休止的向消费者发送消息的问题,并且还保证了消息传递的可靠性。

那么我们将消息的确认策略更换为 MANUAL 手动确认的方式,然后看看这个重试机制的配置会不会生效:

@RabbitListener(queues = Constants.RETRY_QUEUE)
public void listener(Message message, Channel channel) throws IOException, InterruptedException {long deliveryTag = message.getMessageProperties().getDeliveryTag();try {System.out.println("接收到消息:" + message + channel);//制造出异常使得消费者不能正常处理消息int ret = 3/0;System.out.println("消息处理成功");channel.basicAck(deliveryTag,false);} catch (Exception e) {Thread.sleep(1000);//第三个参数requeue表示被拒绝的消息是否重新进入队列,true表示重新进入队列并且重新投递这个消息,否则直接丢弃channel.basicNack(deliveryTag,false,true);}
}

在这里插入图片描述
发现当确认策略为 manual 手动确认的时候,我们的重试机制的配置是不生效的,并且可以发现我们的消息的 deliveryTag 是不断递增的,也就是说之前拒绝的消息每次都会重新入队列然后重新投递,跟重试机制是不一样的。

而如果我们 basicNack 方法的第三个参数 requeue 参数的值为 fasle 时候,那么这个被拒绝的消息就会被丢弃或者投递到的死信队列中。

使用重试机制时需要注意:

  1. 自动确认模式下:程序逻辑出现异常,即使多次重试还是失败,消息也会被自动确认,那么这条消息就会丢失。

  2. 在手动确认模式下,消费者需要显式地发送ACK(Acknowledgment)或NACK来告诉RabbitMQ消息是否已被成功处理。如果发生异常且没有发送ACK,消息将保持为unacked状态,这允许RabbitMQ重新将消息发送给其他消费者(如果配置了多个消费者)或根据队列的其他配置(如死信队列)来处理未确认的消息。然而,如果所有消费者都无法处理该消息,它将导致消息在队列中积压,除非配置了适当的超时机制或死信队列来处理这些长时间未确认的消息。

相关文章:

RabbitMQ 高级特性——重试机制

文章目录 前言重试机制配置文件设置生命交换机、队列和绑定关系生产者发送消息消费消息 前言 前面我们学习了 RabbitMQ 保证消息传递可靠性的机制——消息确认、持久化和发送发确认,那么对于消息确认和发送方确认,如果接收方没有收到消息,那…...

每天一道面试题(20):锁的发生原因和避免措施

死锁的发生原因和避免措施 一、概述 在多线程编程中,死锁是一个常见的问题。理解死锁的成因和避免策略是提升程序稳定性和性能的重要能力。 二、普通人 vs 高手的回答 普通人回答: “临场发挥…” 高手回答: “死锁是指两个或多个线程在执…...

2024淘宝双11活动,收下这份必买好物推荐清单

双11如何真正值得购买的好物呢?为了帮助大家把握住这次难得的购物良机,我们特别推出了这份“2024淘宝双11必买好物推荐清单”。这份清单涵盖数码电子、家居生活、个护健康等多个领域的优质产品。无论你是科技爱好者,还是注重生活品质的消费者…...

vue-cli,element-plus,axios,proxy

一、vue-cli vue-cli俗称vue脚手架,是vue官方提供的快速生成vue 工程化项目的工具。 1.官网:https://cn.vuejs.org/ 中文官网: https://cli.vuejs.org/zh/ 特点:基于webpack,功能丰富且易于扩展,支持创建vue2和vu…...

《Zeotero的学习》

学习视频链接 Zeotera的安装 官网点击download,选择合适的版本进行下载,并安装插件。 下载完成之后,点击安装包,一路默认就可以。如果不想下载在C盘,可以在步骤中选择自定义路径。 Zeotero的注册 官网进行注册&am…...

大数据复习知识点1

1、HDFS和MapReduce的起源:HDFS起源于Google的GFS论文,它是为了解决大规模数据集的存储问题而设计的。而MapReduce则是Google为了解决大规模数据处理问题而提出的一种并行计算模型。 2、YARN的作用:YARN是Hadoop的资源管理器,它负…...

9.26 Buu俩题解

[CISCN2019 华东北赛区]Web2 看wp写完之后写的 知识点 存储型XSS与过滤绕过sql注入 题解 好几个页面,存在登录框可以注册,存在管理员页面(admin.php) ->既然存在管理员页面,且直接访问admin.php提示我们 说明存在身份验证&#xff0…...

Mitsuba 渲染基础

Mitsuba 渲染基础 0. Abstract1. 安装 Mitsuba21.1 下载 Mitsuba2 源码1.2 选择后端 (variants)1.3 编译 2. [Mitsuba2PointCloudRenderer](https://github.com/tolgabirdal/Mitsuba2PointCloudRenderer)2.1 Mitsuba2 渲染 XML2.2 Scene 场景的 XML 文件格式2.2.1 chair.npy to…...

深入理解 WebSocket:实时通信的利器

深入理解 WebSocket:实时通信的利器 1. 什么是 WebSocket? WebSocket 是一种网络通信协议,它允许服务器和客户端之间建立持久的双向通信通道,适用于高频率、低延迟的数据交换场景。在传统的 HTTP 通信中,每次请求都需…...

OpenEuler配置本地yum源

0x00 服务器版本 将本地镜像传输至服务器 操作步骤如下 # 创建一个目录用于挂载光盘映像 mkdir /media/cdrom/# 将光盘映像挂载到指定目录 mount /kvm/openeuler.iso /media/cdrom/#进入Yum仓库配置目录 cd /etc/yum.repos.d/# 备份原有的 openEuler.repo 文件 mv openEuler.…...

论文不同写作风格下的ChatGPT提示词分享

学境思源,一键生成论文初稿: AcademicIdeas - 学境思源AI论文写作 在学术论文写作中,不同的写作风格能显著影响文章的表达效果与读者的理解。无论是描述性、分析性、论证性,还是批判性写作风格,合理选择和运用恰当的写…...

单点登录(SSO)基础

单点登录(SSO, Single Sign-On) 是一种身份认证机制,允许用户在多个独立的应用系统中只进行一次登录操作,即可访问所有授权的应用或服务,而无需每次切换应用时都进行登录。SSO 提高了用户体验的便捷性,同时…...

设置VsCode搜索时排除文件,文件列表中隐藏文件

按照《VsCode gdb gdbserver远程调试C程序》中介绍的方法,配置好VsCode后,打开一个C/C工程,发现左侧的面板会显示编译时生成的中间文件(比如.d和.o文件)。我们可以通过设置隐藏掉一些我们不需要打开的文件以简洁面板…...

急!现在转大模型还来得及吗?零基础入门到精通,收藏这一篇就够了

大模型的出现,让行内和行外大多数人都感到非常焦虑。 行外很多人想了解却感到无从下手,行内很多人苦于没有硬件条件无法尝试。想转大模型方向,相关的招聘虽然层出不穷,但一般都要求有大模型经验。而更多的人,则一直处…...

使用 lstm + crf 实现NER

条件随机场CRF 前言 CRF是给定一组输入随机变量条件下另一组输出随机变量的条件概率分布的模型。特点:假设输出随机变量构成马尔卡夫随机场。CRF可以用于不同的预测问题。但是主要讨论线性链条件随机场,这时问题变成了由输入序列对输出序列的判别模型&…...

【牛掰】这款RPA多平台引流获客软件已正式上线,助您日引流1000+

哈喽大家好我是年哥,自从上次与大家团购了那款基于autojs开发的RPA引流获客的源码,经过本缝合怪不断地修修补补,终于将它变成自己的了,还为它起了个魔幻的名字:获客宝RPA。尽管部分功能还有点瑕疵,但是不管…...

Python的包管理工具pip安装

Python的包管理工具pip安装 一、安装步骤1.检查 pip是否已安装2.安装 pip方法一:通过 ​ensurepip​ 模块安装(推荐)方法二:通过 ​get-pip.py​ 脚本安装(经常应为网络域名问题连接不上) 3.验证pip安装4.创建别名5.更新pip 二、常…...

《AIGC 时代程序员的应对之策》

在 AIGC 大语言模型不断涌现、AI 辅助编程工具日益普及的当下,程序员的工作方式确实面临着深刻变革。对于程序员来说,如何应对这一趋势成为了至关重要的问题。 一方面,有人担忧 AI 可能取代部分编程工作。不可否认,随着技术的发展…...

51单片机系列-串口(UART)通信技术

🌈个人主页: 羽晨同学 💫个人格言:“成为自己未来的主人~” 并行通信和串行通信 并行方式 并行方式:数据的各位用多条数据线同时发送或者同时接收 并行通信特点:传送速度快,但因需要多根传输线&#xf…...

使用k8s部署java前后端服务

一、项目架构 前端、后端、数据库 1)前端 静态的资源:img css html js文件 js:axios、ajax 2)后端 提供数据:根据web前端发送的请求,从数据库中获取数据 请求都是无状态的,如何保持会话 …...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...

线程同步:确保多线程程序的安全与高效!

全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

ESP32读取DHT11温湿度数据

芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...