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重新将消息发送给其他消费者(如果配置了多个消费者)或根据队列的其他配置(如死信队列)来处理未确认的消息。然而,如果所有消费者都无法处理该消息,它将导致消息在队列中积压,除非配置了适当的超时机制或死信队列来处理这些长时间未确认的消息。

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

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

相关文章

C++类和对象——第二关

目录 类的默认成员函数: (一)构造函数 (二)析构函数 (三)拷贝构造函数 类的默认成员函数: 类里面有6个特殊的成员函数分别包揽不同的功能; (一)构造函数…

极狐GitLab 17.4 升级指南

GitLab 是一个全球知名的一体化 DevOps 平台,很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab https://dl.gitlab.cn/6y2wxugm 是 GitLab 在中国的发行版,专门为中国程序员服务。可以一键式部署极狐GitLab。 本文分享极狐GitLab 17.4 升级…

老人跌倒扶不扶?涪城三职工给出响亮答案

一、关键时刻的选择 于绵阳市三江湖湿地公园,平凡午后,三名环卫人员刘后刚、严荣礼及杨树坤正紧张作业。突闻呼救声,一位老人在石阶上跌倒需援手。在紧急关头,他们果断抛却工具,疾速赶至老人身边。此举不仅展现了他们…

MySQL数据库进阶知识(四)《视图、存储过程、触发器》

学习目标: 掌握数据库视图基础知识 掌握数据库存储过程原理 掌握数据库触发器相关知识 学习内容: 一. 视图 介绍 视图(View)是一种虚拟存在的表。视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询…

JPEG图像的DCT(Discrete Cosine Transform)变换公式代码详解

引 言 网络上图像在传输过程中为节省内存空间主要采用jpeg格式。jpeg图属于有损压缩图像的一种。在图像篡改检测过程中,可以利用jpeg图像的单双压缩伪影的不同而判别图像为伪造图并可以定位伪造区域。RGB图像变成jpeg图像过程中涉及从RGB图变成YCbCr图像&#xff0c…

FreeRTOS(四)FreeRTOS列表与列表项

目录 列表 列表项 迷你列表项 列表和列表项的关系 列表相关API函数 列表初始化 列表项初始化 列表项插入 列表项末尾插入 列表项删除 列表遍历 在 FreeRTOS 中,列表(List)和列表项(ListItem)是核心数据结构&…

Centos7系统根分区空间小home空间大如何增加分区

Centos7 默认安装,区划默认划分,用着怎么感觉有问题,根分区太小50G,而home分区太大。 如果处理,能扩大根分区呢?如果是新安装的,可以先删除home,然后再扩容 根分区。最后使其生效。…

计算机视觉硬件整理(四):相机与镜头参数介绍

文章目录 前言一、工业相机常用分类二、工业相机的基本参数三、工业相机的接口四、工业镜头的参数五、工业镜头的选择要点 前言 随着科技的飞速发展,工业自动化和智能制造在当今社会扮演着越来越重要的角色。在这个背景下,工业相机作为一种关键的视觉检…

Qualitor processVariavel.php 未授权命令注入漏洞复现(CVE-2023-47253)

0x01 漏洞概述 Qualitor 8.20及之前版本存在命令注入漏洞,远程攻击者可利用该漏洞通过PHP代码执行任意代码。 0x02 复现环境 FOFA:app"Qualitor-Web" 0x03 漏洞复现 PoC GET /html/ad/adpesquisasql/request/processVariavel.php?gridValoresPopHi…

【azure-openai】批量翻译demo【python】【gradio】

要求:拥有azure-openai-api,上传文件为csv格式,utf-8编码。 注意:如果出现乱码,重新运行,换种方式打开,有时候wps会自动改编码。 实现功能:选择语言,使用gpt4omini&…

使用docker形式部署prometheus+alertmanager+钉钉告警

一、拉取所需要的镜像 docker pull prom/node-exporter docker pull grafana/grafana docker pull prom/prometheus docker pull prom/alertmanager 其中 prom/node-exporter:用于收集主机系统信息和指标的 grafana/grafana:是一个用于可视化和分…

mac 上配置Jmeter代理进行web脚本录制过程容易踩坑的点

macOS 配置 Jmeter代理录制web脚本&容易踩坑的点 mac配置下载:前景提要:Jmeter中具体操作容易踩坑的点1、进入浏览器后,显示访问连接不安全。2、证书失效需要重新生成3、重新生成证书的方式4、没有生成新的证书5、jmeter安装路径找不到 m…

硬件设计很简单?合宙低功耗4G模组Air780E—开机启动及外围电路设计

Air780E是合宙低功耗4G-Cat.1模组经典型号之一,上期我们解答了大家关心的系列问题,并讲解了选型的注意要点。 有朋友问:能不能讲些硬件设计相关的内容? 模组的上电开机,是硬件设计调试的第一步。 本期特别分享——Ai…

MySQL数据库进阶知识(五)《锁》

学习目标: 一周掌握数据库锁相关知识 学习内容: 一. 概述 介绍 锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外,数据也是一种供许多用户共…

将本地文件上传至虚拟机

1、查看虚拟机ip地址 ip addr 2、xshell连接上虚拟机 连接root连接不上的解决办法更改配置文件vim /etc/ssh/sshd_config 重启(sudo service ssh restart)并查看是否开启ssh服务(sudo ps -e | grep ssh) 即可连接成功 3、复制文…

在实时语音交互上超过GPT-4o,端到端语音模型Mini-Omni部署

Mini-Omni是清华大学开源的多模态大型语言模型,具备实时语音输入和流式音频输出的能力。 Mini-Omni模型能够一边听、一边说,一边思考,类似于ChatGPT的语言对话模式。 Mini-Omni模型的主要特点是能够直接通过音频模态进行推理,并…

Skywalking告警配置

背景 skywalking 9.7.0,地址:Backend setup | Apache SkyWalking helm:skywalking-helm:4.5.0,地址:skywalking-helm/chart/skywalking/values.yaml at v4.5.0 首先来说一下为什么使用skywalking告警? …

JS设计模式之组合模式:打造灵活高效的对象层次结构

引言 当我们构建复杂的应用程序时,经常会遇到处理对象层次结构的情况。这些层次结构通常是树形结构,由组合节点和叶子节点组成。在这样的情况下,JavaScript 设计模式之一的组合模式就能派上用场。 组合模式是一种结构型设计模式&#xff0c…

MySQL从入门到精通 - 基础篇

一、MySQL概述 1. 数据库相关概念 二、SQL (1)SQL通用语法 (2)SQL分类 (3)数据定义语言DDL 数据库操作 表操作 数据类型 1. 数值类型 2. 字符串类型 二进制数据:以二进制格式(0和…

【JavaEE初阶】深入解析死锁的产生和避免以及内存不可见问题

前言: 🌈上期博客:【后端开发】JavaEE初阶—线程安全问题与加锁原理(超详解)-CSDN博客 🔥感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客 ⭐️小编会在后端开发的学习中不断更新~~~ &#…