RabbitMQ消息的发布确认机制详解

RabbitMQ发布确认机制确保消息从生产者成功传输到交换机和队列,提高系统可靠性。在Spring Boot项目中,通过配置publisher-confirm-typepublisher-returns,启用发布确认和消息返回机制。配置RabbitTemplate的确认回调和返回回调,可以捕捉消息传输状态,处理不同传输结果。测试场景包括消息无法到达交换机、消息到达交换机但无法到达队列以及消息成功到达队列。通过合理设置和优化,可以确保高并发环境下的消息可靠传输,适用于金融支付、电商系统等对消息传输可靠性要求高的场景。

1. RabbitMQ发布确认机制概述

发布确认(Publisher Confirms)是RabbitMQ提供的一种机制,用于确保消息从生产者发送到RabbitMQ服务器并被成功处理。与事务机制不同,发布确认的性能开销更小,非常适合高吞吐量的场景。发布确认机制提供了两种类型的确认:

  • 消息到达交换机(Exchange)后的确认
  • 消息从交换机路由到队列(Queue)后的确认

2. 配置文件中添加发布确认相关配置

在Spring Boot项目中,通过配置文件来启用发布确认机制非常方便。以下是需要添加到application.propertiesapplication.yml中的配置:

# 消息到达交换机后会回调发送者
spring.rabbitmq.publisher-confirm-type=correlated
# 消息无法路由到队列时回调发送者
spring.rabbitmq.publisher-returns=true

配置解释:

  • publisher-confirm-type:设置为correlated表示使用CorrelationData来关联确认与发送的消息。
  • publisher-returns:设置为true表示启用消息返回机制,当消息无法路由到队列时会触发回调。

3. 发布确认类型

在Spring AMQP中,发布确认类型通过ConfirmType枚举类来定义:

public enum ConfirmType {
    SIMPLE,     // 使用 RabbitTemplate#waitForConfirms() 或 waitForConfirmsOrDie()
    CORRELATED, // 使用 CorrelationData 关联确认与发送的消息
    NONE        // 不启用发布确认
}

4. 配置RabbitTemplate

为了使用发布确认机制,需要配置RabbitTemplate,包括设置确认回调和返回回调:

@Slf4j
@Configuration
public class RabbitTemplateConfig {

    @Bean
    public RabbitTemplate createRabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        rabbitTemplate.setConnectionFactory(connectionFactory);

        // 设置mandatory为true,当找不到队列时,broker会调用basic.return方法将消息返还给生产者
        rabbitTemplate.setMandatory(true);

        // 设置确认回调
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (ack) {
                log.info("消息已经到达Exchange");
            } else {
                log.info("消息没有到达Exchange");
            }
            if (correlationData != null) {
                log.info("相关数据:" + correlationData);
            }
            if (cause != null) {
                log.info("原因:" + cause);
            }
        });

        // 设置返回回调
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
            log.info("消息无法到达队列时触发");
            log.info("ReturnCallback:     " + "消息:" + message);
            log.info("ReturnCallback:     " + "回应码:" + replyCode);
            log.info("ReturnCallback:     " + "回应信息:" + replyText);
            log.info("ReturnCallback:     " + "交换机:" + exchange);
            log.info("ReturnCallback:     " + "路由键:" + routingKey);
        });

        return rabbitTemplate;
    }
}

5. 配置测试交换机和队列

为了测试发布确认机制,我们需要配置相应的交换机和队列:

@Slf4j
@Configuration
public class ConfirmConfig {

    @Bean
    public Queue confirmQueue() {
        return new Queue(Constant.CONFIRM_QUEUE, false);
    }

    @Bean
    DirectExchange confirmExchange() {
        DirectExchange directExchange = new DirectExchange(Constant.CONFIRM_EXCHANGE, false, false);
        directExchange.addArgument("alternate-exchange", Constant.CONFIRM_BACKUP_EXCHANGE);
        return directExchange;
    }

    @Bean
    Binding bindingConfirm() {
        return BindingBuilder.bind(confirmQueue()).to(confirmExchange()).with(Constant.CONFIRM_ROUTING_KEY);
    }

    @Bean
    FanoutExchange backupExchange() {
        return new FanoutExchange(Constant.CONFIRM_BACKUP_EXCHANGE, false, false);
    }

    @Bean
    public Queue backupQueue() {
        return new Queue(Constant.CONFIRM_BACKUP_QUEUE, false);
    }

    @Bean
    public Queue warningQueue() {
        return new Queue(Constant.CONFIRM_WARNING_QUEUE, false);
    }

    @Bean
    Binding bindingConfirmBackup() {
        return BindingBuilder.bind(backupQueue()).to(backupExchange());
    }

    @Bean
    Binding bindingConfirmWarning() {
        return BindingBuilder.bind(warningQueue()).to(backupExchange());
    }
}

6. 测试场景及分析

6.1 消息无法到达交换机

测试代码:

@Autowired
RabbitTemplate rabbitTemplate;
String msg = "一条用于发布确认的消息";

@GetMapping("/noExchange")
public void noExchange() {
    rabbitTemplate.convertAndSend("noExchange", "noExchange", msg);
}

配置了rabbitTemplate.setMandatory(true),当消息无法到达交换机时会回调:

ConfirmCallback 消息没有到达Exchange
ConfirmCallback 原因:channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'noExchange' in vhost '/', class-id=60, method-id=40)

6.2 消息到达交换机但无法到达队列

测试代码:

@GetMapping("/toExchange")
public void toExchange() {
    rabbitTemplate.convertAndSend(Constant.CONFIRM_EXCHANGE, "xxx.xxx.xxx", msg);
}

输出:

ConfirmCallback 消息已经到达Exchange

没有收到无法到达队列的消息,是因为配置了备份队列,消息被路由到了备份队列。

6.3 注掉备份队列再试

修改配置:

@Bean
DirectExchange confirmExchange() {
    DirectExchange directExchange = new DirectExchange(Constant.CONFIRM_EXCHANGE, true, false);
    return directExchange;
}

测试结果:

消息无法到达队列时触发
ReturnCallback:     消息:(Body:'一条用于发布确认的消息' MessageProperties [headers={}, contentType=text/plain, contentEncoding=UTF-8, contentLength=0, receivedDeliveryMode=PERSISTENT, priority=0, deliveryTag=0])
ReturnCallback:     回应码:312
ReturnCallback:     回应信息:NO_ROUTE
ReturnCallback:     交换机:myConfirmExchange
ReturnCallback:     路由键:xxx.xxx.xxx
ConfirmCallback 消息已经到达Exchange

此时,ConfirmCallbackReturnCallback都被调用了。

6.4 成功到达队列

测试代码:

@GetMapping("/toQueue")
public void toQueue() {
    rabbitTemplate.convertAndSend(Constant.CONFIRM_EXCHANGE, Constant.CONFIRM_ROUTING_KEY, msg);
}

输出:

ConfirmCallback 消息已经到达Exchange

7. 发布确认流程

下图展示了RabbitMQ发布确认流程:

image.png

8. 深入解析RabbitMQ发布确认机制

8.1 事务机制与发布确认机制的对比

事务机制和发布确认机制都是确保消息可靠投递的手段,但它们在实现和性能方面有明显区别:

  • 事务机制:通过txSelecttxCommittxRollback实现,性能开销较大,不适合高并发场景。
  • 发布确认机制:通过异步确认消息是否成功到达交换机和队列,性能开销小,适合高并发场景。

8.2 发布确认机制的优缺点

优点
  1. 性能高:相比事务机制,发布确认机制对性能的影响较小。
  2. 异步处理:使用回调函数处理确认结果,不阻塞消息发送。
  3. 可靠性高:确保消息成功到达交换机和队列,提高系统可靠性。
缺点
  1. 实现复杂:需要配置和处理回调函数,增加了代码复杂度。
  2. 延迟高:确认机制引入了额外的网络延迟。

8.3 发布确认机制的应用场景

  1. 金融支付系统:确保支付消息的可靠传输,避免重复支付或支付丢失。
  2. 电商系统:确保订单消息的可靠传输,避免订单丢失或重复处理。
  3. 日志系统:确保日志消息的可靠传输,避免日志丢

失。

8.4 发布确认机制的最佳实践

  1. 合理设置超时时间:在高并发场景下,设置合理的超时时间,避免消息发送阻塞。
  2. 优化回调函数:回调函数中避免复杂逻辑,确保回调处理快速完成。
  3. 监控和报警:建立监控机制,及时发现和处理消息投递失败问题。

9. 总结

本文详细介绍了RabbitMQ消息的发布确认机制,包括配置、实现及其在不同场景下的表现。通过合理配置和使用发布确认机制,可以有效提高消息传输的可靠性,确保消息在高并发环境下的可靠投递。希望本文能够帮助读者深入理解并应用RabbitMQ的发布确认机制,提高系统的可靠性和性能。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

黑龙江等保测评流程

黑龙江的等保测评过程是一个系统严谨的过程&#xff0c;目的在于保证信息系统的安全与机密性符合国家规定的要求。下面将详细介绍黑龙江等保测评的流程&#xff1a; 一、定级与备案 首先&#xff0c;企业要依据自身的业务特点、信息系统的重要性和所承载的信息的敏感程度&…

MyEclipse新手使用介绍

目录 1.MyEclipse诞生背景 2.作用 3.版本历史 4.优缺点 5.应用场景 6.如何使用 6.1.下载与安装 6.2.MyEclipse 菜单及其菜单项 7.创建和发布一个 Java 程序 7.1.创建 Java 程序 7.2.发布 Java 程序 8.示例 8.1. Hello World 示例 8.2. 简单Spring Boot 应用 8.3…

手动安装Nvidia驱动和CUDA Toolkit

1、打开cuda-toolkit 网站 CUDA Toolkit Archive | NVIDIA Developer 根据自己需要选择CUDA Toolkit版本&#xff0c;这里选择12.0.0 2、点击链接跳转到下载页面&#xff0c;选择操作系统类型和安装包类型 3、下载CUDA Toolkit 安装包 4、执行下载命令 wget https://develo…

Sora简介与其对新媒体短视频行业的影响

Sora简介 官网&#xff1a;https://openai.com/sora 当大家还在沉浸在GPT各种大语言模型的时候&#xff0c;OpenAI 悄无声息地发布了文生视频&#xff08;text-to-video&#xff0c;简称 t2v&#xff09;模型 Sora&#xff0c;这又是一个对AI冲击很大的突破了。Sora可以根据文…

什么是广告联盟变现

广告联盟变现&#xff0c;作为一种连接广告主与各类媒体平台的机制&#xff0c;正展现出强大的生命力和影响力。它为拥有流量资源的一方提供了将其转化为实际经济收益的有效途径。通过广告联盟&#xff0c;媒体平台可以与众多广告主建立合作关系&#xff0c;获取多样化的广告内…

Ubuntu系统安装docker以及安装yg系统所能使用到的插件

Ubuntu系统安装docker以及安装yg系统所能使用到的插件 前言&#xff1a;建议大家使用ubuntu系统的时候&#xff0c;直接永久关闭防火墙目前我们处于学习状态&#xff0c;这样有利于提高开发效率。 文章目录 Ubuntu系统安装docker以及安装yg系统所能使用到的插件一、安装docker二…

docker 拉取不到镜像的问题:拉取超时

error pulling image configuration: download failed after attempts6: dial tcp 31.13.94.10:443: i/o timeout 首先设置国内的镜像源&#xff1a;复制下面直接执行 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-EOF{"registry-mirrors"…

通过在idea上搭建虚拟hadoop环境使用MapReduce做词频去重

idea上的MapReduce ​ 一般在开发中&#xff0c;若是等到环境搭配好了再进行测试或者统计数据&#xff0c;数据处理等操作&#xff0c;那会很耽误时间&#xff0c;所以一般都是2头跑&#xff0c;1波人去在客户机上搭建环境&#xff0c;1波人通过在idea上搭建虚拟hadoop环境&am…

uni-app uni-swipe-action 滑动操作状态恢复

按照uni-app官方文档的写法 当前同一条滑动确认之后 页面列表刷新 但是滑动的状态还在 入下图所示&#xff1a; 我们需要在滑动确认之后 页面刷新 滑动状态恢复 那么我们就来写一下这部分的逻辑&#xff1a; 首先&#xff0c;配置一下:show"isOpened[item.id]" chan…

学习笔记——网络参考模型——TCP/IP模型(网络层)

三、TCP/IP模型-网络层 1、IPV4报头 (1)IPV4报文格式 IP Packet(IP数据包)&#xff0c;其包头主要内容如下∶ Version版本∶4 bit&#xff0c;4∶表示为IPv4; 6∶表示为IPv6。 Header Length首部长度∶4 bit&#xff0c;代表IP报头的长度(首部长度)&#xff0c;如果不带Opt…

传输协议TCP-原理部分

传输控制协议TCP&#xff08;Transmission Control Protocol&#xff09;一种基于连接的可靠的稳定的无重复的传输协议。 1、TCP头部信息 TCP协议头部信息如下&#xff1a; 一共占用20个字节 16位源端口号&#xff1a;发送进程的主机端口16位目的端口号&#xff1a;接收主机…

工作备忘录软件有哪些 记事备忘提醒三合一的备忘录

在工作中&#xff0c;我总是觉得自己脑子好像不够用&#xff0c;一会儿是这个项目的进度要跟踪&#xff0c;一会儿是那个会议的要点要记录。每天都在忙碌与混乱中度过&#xff0c;我甚至开始怀疑自己是否适合这份工作。 备忘录不仅是一个简单的记事工具&#xff0c;像敬业签这…

MyBatis总结(2)- MyBatis实现原理(一)

Mybatis实现原理&#xff1a; 概括一句话&#xff1a;约定配置参数mybatis-config.xml&#xff0c;映射关系JavaBean-mapper.xml&#xff0c;用SqlSessionFactoryBuilder构建应用程序运行期间需要的SqlSessionFactory实例对象&#xff0c;当请求或方法需要执行CURD操作时&…

matlab使用教程(92)—流线图、流带图和流管图

1.使用向量数据显示流线图 MATLAB 向量数据集 wind 代表北美地区的气流。本示例结合使用了几种方法&#xff1a; 利用流线跟踪风速 利用切片平面显示数据的横截面视图 利用切片平面上的等高线提高切片平面着色的可见性 1.1确定坐标的范围 加载数据并确定用来定位切片平面…

TypeScript系列之-- 带你深层次理解对象类型回归本质探究原理

描述对象的数据类型&#xff1a; 使用class/constructor描述用type或interface描述 使用class/constructor描述 const a: Date ()> console.log(1) // Error 会报错缺少日期的一些属性 const a: Function ()> console.log(1) // Ok class Person { name: string …

行心科技中禄松波携手,开启智能健康新时代

在2024年第34届健博会暨中国大健康产业文化节的盛大舞台上&#xff0c;广州市行心信息科技有限公司&#xff08;以下简称“行心科技”&#xff09;与浙江中禄松波生物工程有限公司&#xff08;以下简称“中禄松波”&#xff09;宣布达成战略合作&#xff0c;共同推动医康养产业…

企业建站响应式网站建设平台版源码系统 海量模版可选择 带完整的安装代码以及搭建教程

系统概述 企业建站响应式网站建设平台版源码系统是一款集创新性、实用性和便捷性于一体的建站解决方案。它旨在为用户提供一站式的网站建设服务&#xff0c;无论你是新手还是经验丰富的开发者&#xff0c;都能通过该系统轻松实现网站的构建与部署。 该系统采用先进的技术架构…

数据结构——算法和算法效率的度量

目录 一、引言 二、算法 1 算法的基本概念 2 算法的复杂度 2.1 时间复杂度 2.1.1 概念 2.1.2 大O的渐进表示 3 算法的空间复杂度 3.1 概念 3.2 实例 4 实例分析 5 结论 一、引言 大家在写代码的时候有没有发现写同样功能的代码有多种不同的写法&#xff0c;而不同的代…

Lab_ Finding and exploiting an unused API endpoint

https://portswigger.net/web-security/learning-paths/api-testing/api-testing-identifying-and-interacting-with-api-endpoints/api-testing/lab-exploiting-unused-api-endpoint# 查看功能点&#xff1a; 在Burp的HTTP history中发现 /api路径 我们先尝试一下将API请求…

ArcGIS JSAPI 学习教程 - ArcGIS Maps SDK for JavaScript - 框选显示高亮几何对象

ArcGIS JSAPI 学习教程 - ArcGIS Maps SDK for JavaScript - 框选显示高亮对象 核心代码完整代码&#xff1a;在线示例 在研究 ArcGIS JSAPI RenderNode 高亮&#xff08;highlights&#xff09;FBO 的时候&#xff0c;实现了一下框选高亮几何对象&#xff0c;这里分享一下。 …