集成框架-RabbitMQ重试和确认

SpringBoot+RabbitMQ_消息确认机制、消息重试机制 一、前言 使用RabbitMQ,会有知晓消息是否成功、如果消费失败重试的需求,这篇文章主要讲的是消息确认机制(ACK)和消息重试机制。 二、消息确认机制 RabbitMQ的消费者确认机制用来确认消费者是否成功消费了队列中的消息。 消息确认分为几种情况: AcknowledgeMode.NONE:不确认,不发送任何ack确认;只要消息发送完成会立即在队列移除,不会重发。 AcknowledgeMode.AUTO:自动确认,消费消息后会自动发送ack确认;在消费... 阅读详情

前言:

关于消息重试

在 Spring Boot 中,你可以使用 yml 格式的配置文件来配置 RabbitMQ 的重试机制。

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
    listener:
      simple:
        retry:
          enabled: true
          initial-interval: 5000 # 初始重试间隔时间(毫秒)
          max-attempts: 3 # 最大重试次数
          max-interval: 10000 # 最大重试间隔时间(毫秒)
          multiplier: 2.0 # 重试间隔时间倍数

在这个配置中,启用了 RabbitMQ 的重试机制,并指定了重试的初始间隔时间、最大重试次数、最大重试间隔时间和重试间隔时间的倍数。


关于消息确认

当消费者处理消息时,如果处理成功,可以使用确认机制告知RabbitMQ已经成功消费了该消息。如果处理失败,则消息会被重新放回队列,等待重试。下面是一个演示确认机制的示例:

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import com.rabbitmq.client.Channel;

@Component
public class MessageConsumer {

    @RabbitListener(queues = "retry_queue")
    public void handleMessage(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws Exception {
        try {
            System.out.println("Received message: " + message);
            // 在这里进行消息处理
            // 如果处理成功,手动确认消息
            channel.basicAck(tag, false);
        } catch (Exception e) {
            // 如果处理失败,可以选择手动拒绝消息并重新放回队列,或者进行其他处理
            System.out.println("Failed to process message: " + e.getMessage());
            // 手动拒绝消息并重新放回队列
            channel.basicReject(tag, true);
        }
    }
}

正文

消息重试

当消费者报错时,RabbitMQ 将会使用 yml 配置文件中设置的重试策略对消息进行重试。

添加 spring-boot-starter-amqp 依赖:

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

amqp 是什么在rabbitmq中有什么作用呢,amqp是异步消息传输的协议 它定义了消息的传输格式、消息交换模式、队列管理方式等


下面是 AMQP 在 RabbitMQ 中的一些网络文章罗列的作用:

  • 消息格式定义: 定义了消息的格式,包括消息的头部、属性、内容等。消息的格式化使得消息在不同的应用程序之间可以被正确地解析和处理。

  • 消息交换模式: 定义了消息的交换模式,包括直接交换、扇出交换、主题交换等。这些交换模式使得消息可以被路由到不同的队列,以满足不同的业务需求。

  • 队列管理: 定义了队列的管理方式,包括队列的创建、删除、绑定、解绑等操作。这些操作使得队列可以被动态地管理和调整,以适应不同的应用场景。

  • 消息确认机制: 提供了消息确认机制,包括自动确认和手动确认两种模式。消息确认机制可以确保消息被正确地接收和处理,从而提高了消息传输的可靠性和稳定性。

  • 事务支持: 支持事务,可以保证一组消息的原子性操作。事务机制可以确保消息的原子性,从而保证消息的一致性和可靠性。

然后,可以在配置文件中配置RabbitMQ连接信息和重试策略:

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
    listener:
      simple:
        retry:
          enabled: true
          initial-interval: 5000 # 初始重试间隔时间(毫秒)
          max-attempts: 3 # 最大重试次数
          max-interval: 10000 # 最大重试间隔时间(毫秒)
          multiplier: 2.0 # 重试间隔时间倍数

接下来,编写一个生产者,用于发送消息到 RabbitMQ:

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MessageProducer {

    @Autowired
    private AmqpTemplate amqpTemplate;

    public void produceMessage(String message) {
        amqpTemplate.convertAndSend("retry_exchange", "retry_key", message);
    }
}

然后,编写一个消费者,用于消费消息并故意引发异常:

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class MessageConsumer {

    @RabbitListener(queues = "retry_queue")
    public void handleMessage(String message) throws Exception {
        System.out.println("Received message: " + message);
        // 模拟处理消息时发生异常
        throw new RuntimeException("Simulated exception occurred");
    }
}

最后,在你的应用程序入口,创建一个简单的控制器,用于触发消息的发送:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class Application {

    @Autowired
    private MessageProducer messageProducer;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @GetMapping("/send")
    public String sendMessage() {
        messageProducer.produceMessage("Hello RabbitMQ!");
        return "Message sent to RabbitMQ";
    }
}

现在,当启动应用程序并访问 /send 路径时,生产者将发送一条消息到 RabbitMQ,然后消费者将会接收到这条消息,并故意引发异常。Rabbitmq 将根据配置文件中的重试策略对消息进行重试,直到达到最大重试次数为止。


消息重试总结

以上就是消息重试的概念,关于如果不是一个服务,比如生产者配置3次指的是生产者发送失败重试的次数,消费者配置3次指的是消费者重试的次数,只要配置了,如果消费报错就会重试,生产报错也会重试,如果生产消费在一起,就是消费报错重试。


消息确认

当消费者处理消息时,如果处理成功,可以使用确认机制告知 RabbitMQ 已经成功消费了该消息。如果处理失败,则消息会被重新放回队列,等待重试。下面是一个确认机制的示例:


首先,确保你的消费者方法使用了@RabbitListener注解,并且使用Channel对象进行手动确认。这样,你就可以在消费者成功处理消息时手动确认消息:

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import com.rabbitmq.client.Channel;

@Component
public class MessageConsumer {

    @RabbitListener(queues = "retry_queue")
    public void handleMessage(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws Exception {
        try {
            System.out.println("Received message: " + message);
            // 在这里进行消息处理
            // 如果处理成功,手动确认消息
            channel.basicAck(tag, false);
        } catch (Exception e) {
            // 如果处理失败,可以选择手动拒绝消息并重新放回队列,或者进行其他处理
            System.out.println("Failed to process message: " + e.getMessage());
            // 手动拒绝消息并重新放回队列
            channel.basicReject(tag, true);
        }
    }
}

这里使用 channel.basicAck(tag, false) 方法手动确认消息。如果消费者成功处理消息,则调用这个方法告知 RabbitMQ 已经成功消费了该消息。如果处理失败,则可以选择手动拒绝消息并重新放回队列,或者进行其他处理。如果你不用channel.basicAck(tag, false) 和没有引入@Header(AmqpHeaders.DELIVERY_TAG) long tag 默认的话是自动确认。

所以确保在消费者方法的参数列表中包含 Channel 对象和消息的DELIVERY_TAG。这样,Spring AMQP 就会将 Channel 对象注入到消费者方法中,以便你可以使用它来手动确认消息。

这样,当消费者处理消息时,你就可以使用确认机制告知RabbitMQ消息的处理结果。如果处理成功,则消息被消费,否则消息会被重新放回队列等待重试。

在 RabbitMQ 中,生产者并不会直接接收到消费者的确认请求。确认请求是由消费者向 RabbitMQ 服务器发送的,用于告知RabbitMQ消息的处理结果。生产者可以选择监听确认事件,以便在消息被确认后执行相应的操作。

在 Spring Boot 中,可以使用 RabbitTemplate 的 ConfirmCallback 接口来监听确认事件。以下是一个生产者简单的示例:

import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MessageProducer {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void produceMessage(String message) {
        CorrelationData correlationData = new CorrelationData("unique-id"); // 设置消息的唯一标识符
        rabbitTemplate.convertAndSend("retry_exchange", "retry_key", message, correlationData);
        
        // 设置 ConfirmCallback,用于监听消息的确认结果
        rabbitTemplate.setConfirmCallback((correlation, ack, cause) -> {
            if (ack) {
                // 如果消息被确认
                System.out.println("Message with correlation id " + correlation.getId() + " confirmed");
            } else {
                // 如果消息被拒绝或超时
                System.out.println("Message with correlation id " + correlation.getId() + " rejected: " + cause);
            }
        });
    }
}

在这个示例中,通过CorrelationData设置了消息的唯一标识符,并将其作为参数传递给 convertAndSend 方法。然后,我们设置了 ConfirmCallback,用于监听消息的确认结果。当消息被确认时,ConfirmCallback的ack 参数将会为 true,表示消息被成功确认;当消息被拒绝或超时时,ack 参数将会为 false,同时 cause 参数将会包含拒绝的原因。

通过监听 ConfirmCallback,生产者可以在消息被确认时执行相应的操作,例如记录日志、更新状态等。

确认机制和重试机制的概念

在 RabbitMQ 中,消息的确认机制和重试机制是两个不同的概念,它们可以结合使用,但并不互相排斥。确认机制是用来告知 RabbitMQ 消息的处理结果,而重试机制则是在消息处理失败时将消息重新放回队列,等待后续的重试。

如果消息被消费者确认了(即消费者成功处理了消息),RabbitMQ 将会将该消息从队列中删除,不会再进行重试。这意味着即使消息在处理过程中出现了错误,但只要消费者成功确认了该消息,它就不会再次被放回队列进行重试。

然而,如果消费者拒绝了消息(即调用了 channel.basicReject(tag, true) 方法),或者处理消息时发生了超时等问题,RabbitMQ 将会将消息重新放回队列,等待后续的重试。这时,重试机制会起作用,根据配置的重试策略对消息进行重试,直到达到最大重试次数为止。

因此,确认机制和重试机制是可以结合使用的。确认机制用于告知 RabbitMQ 消息的处理结果,而重试机制则用于处理处理失败的消息,确保消息能够被成功处理。
如果按上文配置重试3次,那么生产者方法,会在第一次报错他被拒绝了,但是任然还会在队列里面重试3次才会结束,这就涉及到消息积压。这要注意

RabbitMQ重试机制 1、RabbitMQ重试机制的简介 RabbitMQ 不会为未确认的消息设置过期时间,它判断此消息是否需要重新投递给消费者的唯一依据是消费该消息连接是否已经断开,这个设置的原因是 RabbitMQ 允许消费者消费一条消息的时间可以很久很久。 RabbitMQ 的 Web 管理平台上可以看到当前队列中的 “Ready” 状态和 “Unacknowledged” 状态的消息数,分别对应等待投递给消费者的消息数和已经投递给消费者但是未收到确认信号的消息数。如下图: 注意事项: 如果在处理消息的过程中 阅读详情

相关推荐

RabbitMQ 高级特性——重试机制

RabbitMQ重试机制

不能再留遗憾了的博客 2641

Redis 客户端重试指南

在互联网服务中,特别是在云环境下,网络及硬件环境复杂,所有应用程序都可能遇到暂时性故障。暂时性故障包括瞬时的网络抖动,服务暂时不可用,服务繁忙导致超时等,这些故障通常可以自我修复,在间隔一定时间后重试,则很大概率可以成功。 ​ 为什么会出现暂时性故障 云 Redis 集群的高可用 云 Redis 集群或者云环境中的很多产品,都是由大量机器组成的集群提供服务,机器可能发生各种各样的硬件故障,比如 CPU,内存,磁盘 都可能发生故障。当故障发生时,Redis 服务会自动做 HA (High Available)

杨博东的博客 2633

【AirSim+PX4】WSL2上运行PX4连接Airsim步骤

在 Linux 命令行中输入以下命令以添加(或改变)环境变量。注意,此处的 IP 地址应为。4.启动 sln 文件的调试以进入 UE4 编辑器,并在 Linux 中启动 PX4。

m0_53538421的博客 1505

【中间件】RabbitMQ 自定义重试次数(针对同一模块不同消费者)

最近遇到了关于 RabbitMQ 的问题,打比方说:某个微服务模块中,RabbitMQ 的大部分消费者需要重试两次,而小部分消费者由于特殊原因并不需要进行重试。这就涉及到自定义重试次数的话题了,但在网上找了一圈没发现相关的,但是功夫不负有心人,最后还是解决了这个问题,接下来给大家分享一下~

尹煜的博客 7037

【数学建模】 进化计算与群体智能

遗传算法(GA)是一种用于优化和搜索问题的启发式算法。它模拟了自然选择的过程,其中个体通过遗传和变异进行繁殖,逐渐进化出更优的解。基本步骤初始化:生成初始种群。适应度评估:评估种群中每个个体的适应度。选择:根据适应度选择个体进行繁殖。交叉:选定个体对进行基因交换,生成新的后代。变异:对一些个体进行基因变异,以增加多样性。迭代:重复评估和繁殖过程,直至达到停止条件。粒子群优化算法(PSO)是一种基于群体智能的优化算法,由Kennedy和Eberhart于1995年提出。其灵感来源于鸟群觅食的行为。

weixin_42914989的博客 1112

ESP-01S获取网络时间踩坑全记录:AT指令调试、JSON解析乱码、时区处理,一个都不能少

本文详细记录了使用ESP-01S WIFI模块获取网络时间的完整过程,包括AT指令调试、JSON解析乱码处理以及时区转换等关键步骤。通过实战案例和代码示例,帮助开发者避开常见陷阱,实现稳定的网络时间同步功能。

weixin_30460489的博客 295

RabbitMQ之消息重试机制

RabbitMQ之消息重试机制

qq_43654581的博客 8269

【嵌入式面经】上海 70迈 线上笔试

“关注|点赞|收藏” 福利干货第一时间送达!最近在做免费的嵌入式知识分享,帮助对嵌入式感兴趣的同学学习嵌入式、做项目、找工作!

qq_56921854的博客 1134

rabbitmq 重试机制

当消息发送到RabbitMQ时,可能会出现一些问题,例如网络故障、消费者不可用等,导致消息无法成功发送或消费。重试机制是指在消息发送或消费过程中,当出现错误或失败时,RabbitMQ会自动尝试重新发送或消费消息,直到达到一定的重试次数或达到一定的时间限制。​方法将消息重新发送到队列,实现了重试机制。需要注意的是,上述代码只是一个示例,实际应用中还需要根据具体需求和场景进行一些改进和优化,例如设置重试次数限制、处理死信消息等。​函数中,首先模拟处理消息时出现了异常,然后拒绝该消息,表示不再重试。

牛肉胡辣汤 2571

算法竞赛入门到进阶 --- 完整学习路线(含知识点讲解)

前言: 咳咳,接触算法竞赛也有一年了,却从来都没有进行过一次系统的学习,稀里糊涂的就这么搞了半年,如今,我决定认认真真的进行一次系统的复盘。嗯嗯,先把大体路线列出来,然后往后每天搞几篇,可能大三能完成,可能永远也不能写完这些,我只能慢慢来,一起共勉吧。冲了!(主要是太菜了,不系统学习下,怕是铜牌都拿不到呀!) 算法竞赛入门到进阶一、sort函数自定义排序二、c++容器的使用1.vector动态数组2.stack栈3.queue队列4.list链表5.set集合6.map映射三、二进制子集生成四、bfs.

qq_43514659的博客 2万+

TCN(Temporal Convolutional Networks)时序卷积网络详解及代码

TCN(Temporal Convolutional Networks)时序卷积网络详解及代码

zhulewen的博客 7880

MQ消息重试

超过1秒没发送成功就重试,重试10次。

qq_41273137的博客 329

零基础也能懂的Arduino ESP32离线安装包图文教程

手把手教你完成Arduino ESP32离线安装包的配置,无需联网也能快速搭建开发环境,适合初学者和网络受限用户,轻松实现arduino esp32离线安装包部署。

weixin_36213081的博客 2658

spring amqp AmqpTemplate(4)

与Spring框架和相关项目提供的许多其他高级抽象一样,Spring AMQP提供了一个“模板”,它扮演着核心角色。定义主要操作的接口称为AmqpTemplate。这些操作涵盖了发送和接收消息的一般行为。换句话说,它们对于任何实现都不是惟一的——因此名称中有“AMQP”。另一方面,该接口的一些实现与AMQP协议的实现绑定在一起。与JMS本身是接口级API不同,AMQP是一个线级协议。该协议的实现提...

xiaoliuliu2050的专栏 2824

ESP32S3接入讯飞在线语音识别教程及配套源代码

本文介绍了如何使用ESP32-S3开发板实现讯飞在线语音识别功能。首先,需要准备硬件设备,包括ESP32-S3开发板、麦克风模块、MicroSD卡模块和扬声器模块。接着,安装Arduino IDE并配置ESP32-S3开发环境,注册讯飞开放平台账号并获取API凭证。然后,通过I2S接口连接麦克风模块,并编写代码实现语音录制、Base64编码、API请求和识别结果处理。代码包括初始化WiFi、麦克风、系统时间,以及录制语音、发送请求、解析响应等功能。最后,通过按键触发录音,并将识别结果输出到串口。

2401_88800025的博客 746

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

motia与消息队列集成:RabbitMQ使用教程

在现代分布式系统中,事件驱动架构(Event-Driven Architecture, EDA)已成为构建高可扩展性、松耦合系统的首选方案。Motia作为一个基于事件的编排框架(Event-based orchestration framework),原生支持事件的发布与订阅机制。然而,当系统规模扩大到跨服务、跨节点通信时,内存中的事件总线已无法满足可靠性和分布式需求。这时,引入专业的消息队列(M...

gitblog_00521的博客 992

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Maomi.MQ 2.0 | 功能强大的 .NET 消息队列通讯模型框架

说明作者:痴者工良文档地址:https://mmq.whuanle.cn仓库地址:https://github.com/whuanle/Maomi.MQ作者博客:• https://www.whuanle.cn• https://www.cnblogs.com/whuanle导读Maomi.MQ 是一个简化了消息队列使用方式的通讯框架,目前支持了 RabbitMQ。Maomi.MQ.RabbitM...

dotNET跨平台 4708

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

graphify 实战案例研究:对 rsl-siege-manager 全栈仓库执行混合语言知识图谱提取

本篇案例研究带你完整复盘 graphify 的一次真实 dry-run:对 `rsl-siege-manager`——一个同时包含 Python(FastAPI)后端、TypeScript(React + Vite)前端与 Python Discord Bot 的单仓全栈项目——执行 `graphify extract`,得到包含 1886 节点、3876 边的可查询知识图谱。读完后你将掌握完整复

gitblog_00851的博客 627

7步掌握Egg.js与RabbitMQ集成:构建企业级异步处理架构的完整指南

Egg.js作为基于Node.js和Koa的企业级框架,为开发者提供了稳定高效的应用开发体验。本文将通过7个实用步骤,详解如何在Egg.js项目中集成RabbitMQ消息队列,帮助你构建高可用的异步处理系统,轻松应对高并发场景下的任务处理需求。 [![Egg.js企业级框架](https://raw.gitcode.com/gh_mirrors/eg/egg/raw/f9b94d6533604e

gitblog_00291的博客 332

详解RabbitMQ高级特性之重试机制

详解RabbitMQ高级特性之重试机制。

. 1999

【Rabbitmq篇】RabbitMQ⾼级特性----持久性,发送⽅确认,重试机制

介绍【Rabbitmq篇】RabbitMQ⾼级特性----持久性,发送⽅确认,重试机制

chaodddddd的博客 8459

RabbitMq手动确认时的重试机制

消息手动确认模式的几点说明 监听的方法内部必须使用channel进行消息确认,包括消费成功或消费失败 如果不手动确认,也不抛出异常,消息不会自动重新推送(包括其他消费者),因为对于rabbitmq来说始终没有接收到消息消费是否成功的确认,并且Channel是在消费端有缓存的,没有断开连接 如果rabbitmq断开,连接后会自动重新推送(不管是网络问题还是宕机) ...

HELLOW,文浩 7412

【RabbitMQ】重试机制、TTL

对于RabbitMQ的重试机制以及过期时间的简单概述

weixin_73060900的博客 1969

rabbitmq消费消息确认及消费失败重试机制

这里主要是针对springboot中的rabbitmqtemplate来说的 基础代码以查看此专栏相关文章 消费者消息确认 RabbitMQ是阅后即焚机制,RabbitMQ确认消息被消费者消费后会立刻删除。 而RabbitMQ是通过消费者回执来确认消费者是否成功处理消息的:消费者获取消息后,应该向RabbitMQ发送ACK回执,表明自己已经处理消息。 设想这样的场景: 1)RabbitMQ投递消息给消费者 2)消费者获取消息后,返回ACK给RabbitMQ 3)RabbitMQ删除消息 4)消费者宕机,消

优雅永不过时 1万+

【RabbitMQ】RabbitMQ 消息的可靠性 —— 生产者和消费者消息的确认,消息的持久化以及消费失败的重试机制

在现代分布式应用程序中,消息队列扮演了至关重要的角色,允许系统中的各个组件之间进行异步通信。这种通信模式提供了高度的灵活性和可伸缩性,但也引入了一系列的挑战,其中最重要的之一是消息的可靠性。首先让我们来了解一下,在消息队列中,消息从生产者发送到交换机,再到队列,最后到消费者,有哪些情况会导致消息的丢失?生产者发送的消息未送达交换机;消息到达交换机后未到达队列;MQ 宕机,队列中的消息会丢失;消费者接收到消息后未消费就宕机了。

qq_61635026的博客 1万+
上一篇: mysql: docker 异常 - mbind: Operation not permitted
下一篇: 运维出现的问题 --集成
徐寿春
博客等级 码龄8年 469粉丝 289原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值