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

RabbitMQ 如何保证消息不丢失?

为了保证消息在 RabbitMQ 中不丢失,必须从生产者、Exchange 路由、Broker 和消费者等多个方面采取有效措施。RabbitMQ 消息丢失的场景主要分为以下三种情况:生产者端、路由过程以及消费者端。

一、RabbitMQ 消息丢失的三种情况

在讨论如何保证消息不丢失之前,我们先来看看一条消息从生产到消费的完整流程:

  1. 生产者将消息发送到Exchange
  2. Exchange根据Routing Key将消息路由到Queue
  3. 消费者订阅Queue,从Queue中获取消息进行消费。
消息丢失可能发生在以下几个阶段:
  1. 生产者丢失消息:生产者在将消息发送到 Exchange 的过程中,由于网络问题或发送到不存在的 Exchange,导致消息丢失。

  2. 路由失败:消息发送到了 Exchange,但 Exchange 在根据 Routing Key 路由时没有找到对应的 Queue,导致消息没有进入任何 Queue,从而丢失。

  3. 消费者处理失败:消费者已经成功从 Queue 中获取了消息,但在处理过程中发生异常,消息未正确处理或确认(ACK),导致消息丢失。

其他情况:RabbitMQ 服务崩溃时的消息丢失

即便上述问题都解决了,如果 RabbitMQ 服务器宕机且消息未被持久化,服务重启后这些未持久化的消息仍会丢失。因此,消息的持久化也是关键一环。


二、RabbitMQ 消息丢失的解决方案

针对不同的丢失场景,RabbitMQ 提供了多种机制来解决这些问题:

2.1 针对生产者端消息丢失
问题:生产者发送消息到 Exchange 时,由于网络问题或目标 Exchange 不存在,导致消息丢失。

解决方案:
RabbitMQ 提供了两种方式来解决生产者端的消息丢失问题:事务机制和发布确认机制。

(1)事务机制(不推荐,性能较差)

生产者可以在发送消息之前开启 RabbitMQ 事务,通过以下步骤确保消息不会丢失:

  1. 开启事务:channel.txSelect()
  2. 发送消息:channel.basicPublish()
  3. 如果发送成功,提交事务:channel.txCommit();否则,回滚事务:channel.txRollback(),并重试发送。

事务机制虽然可以确保消息可靠性,但由于性能问题不适合高并发场景。

(2)发布确认机制(推荐)

发布确认机制是一种更高效的方案,生产者在发送消息后可以收到 RabbitMQ 的确认(ACK)或否定确认(NACK)。步骤如下:

  1. 开启发布确认模式:channel.confirmSelect()
  2. 监听确认回调:
    • onAck():消息成功发送到 Broker。
    • onNack():消息发送失败,生产者可以选择重新发送。

发布确认模式不仅能够保证消息不会丢失,而且性能较事务模式要高得多,是生产环境中首选的方案。


2.2 针对路由失败
问题:消息到达了 Exchange,但由于没有合适的 Queue 路由,消息丢失。

解决方案:
通过配置 RabbitMQ 的备份交换机(Alternate Exchange,AE)和Mandatory 参数来处理消息的路由失败问题。

(1)Mandatory 参数

设置 mandatory=true,如果消息无法路由到任何 Queue,RabbitMQ 会将消息返回给生产者,生产者可以选择处理返回的消息或进行重试。

channel.basicPublish(exchange, routingKey, true, null, message);

 

(2)备份交换机(AE)

备份交换机是当消息未成功路由到 Queue 时,将消息路由到一个备用的 Exchange,确保消息不会丢失。例如,某些高优先级的消息可以转到备份交换机做进一步处理或记录。


2.3 针对消费者端消息丢失
问题:消费者已经从 Queue 中获取消息,但在处理消息时发生了异常,没有返回 ACK,导致消息丢失。

解决方案:
使用手动确认模式代替自动确认,确保消费者在成功处理完消息后才返回确认。

  1. 手动确认模式:
    • 在消费者处理完消息后,手动调用 channel.basicAck() 来确认消息处理成功。
    • 如果消息处理失败,可以调用 channel.basicNack()channel.basicReject() 来拒绝该消息,RabbitMQ 会重新将消息投递给其他消费者
    • 持久化消费者状态:为了防止在处理消息过程中出现宕机等意外情况,消费者可以将消息处理过程中的中间状态持久化到数据库,确保即使消费者宕机也可以继续未完成的工作。

    • 2.4 RabbitMQ 服务宕机时的消息丢失
      问题:RabbitMQ 宕机导致未持久化的消息丢失。

      解决方案:
      通过持久化消息、队列和集群部署来提高消息的可靠性。

      (1)消息持久化

      生产者可以将消息标记为持久化消息,确保 RabbitMQ 崩溃重启后消息不会丢失:

      MessageProperties.PERSISTENT_TEXT_PLAIN  // 持久化消息
      
      (2)队列持久化

      除了消息,队列本身也需要设置为持久化队列。即使 RabbitMQ 重启,队列依然存在并保存消息:

      channel.queueDeclare("queueName", true, false, false, null);
      
      (3)镜像队列

      为了防止单点故障,可以采用镜像队列,即在 RabbitMQ 的多个节点上复制队列。当主节点宕机时,副本节点可以继续处理消息,保证消息的可靠性。


      三、总结

      要保证 RabbitMQ 的消息不丢失,需要从生产者、路由过程、消费者和 Broker 端采取一系列措施。消息丢失的常见原因包括:生产者发送失败、消息路由失败、消费者处理异常,以及 RabbitMQ 服务宕机未持久化。

      为解决生产者端的消息丢失问题,可以采用事务机制或发布确认机制,确保消息成功发送并得到确认。路由过程中,可以通过 mandatory 参数或设置备份交换机来处理路由失败的情况,确保消息到达队列。消费者端则应使用手动确认模式,保证消息处理完成后才返回 ACK,避免因处理失败导致消息丢失。同时,在 RabbitMQ 宕机的情况下,通过持久化消息和队列、配置镜像队列等方式保证消息不会丢失。

      综合以上机制,RabbitMQ 提供了一个较为全面的消息可靠性保证方案,虽然不能确保 100% 消息不丢失,但可以最大程度上减少消息丢失的风险。

相关文章:

RabbitMQ 如何保证消息不丢失?

为了保证消息在 RabbitMQ 中不丢失,必须从生产者、Exchange 路由、Broker 和消费者等多个方面采取有效措施。RabbitMQ 消息丢失的场景主要分为以下三种情况:生产者端、路由过程以及消费者端。 一、RabbitMQ 消息丢失的三种情况 在讨论如何保证消息不丢…...

Oracle或者PL/SQL导入pde文件

目录 pde文件使用pl/sql developer的 tools-> import tables-> pl/sql developer来导入;...

【QAMISRA】解决导入commands.json时报错问题

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 解决导入commands.json时报错“Could not obtain system-wide includes and defines”的问题。 2、 问题场景 客户导入commands.json时报错“Could not obtain system-wide includes and defines”。 3、软硬件环境…...

影刀RPA实战番外:excel函数应用指南

Excel函数是用于执行特定计算、分析和数据处理任务的预定义公式。它们可处理数学计算、文本处理、逻辑判断、日期和时间运算、查找和引用数据等。例如,SUM函数可以计算一系列数字的总和,IF函数进行逻辑测试,VLOOKUP函数在表格中查找数据&…...

php生成PDF文件(FPDF)

FPDF即“Free PDF”,FPDF类库提供了基本的PDF创建功能,其源代码和使用权是免费的。 PDF格式文档优势 通用:PDF文档在UNIX和Windows系统均可正常使用。 安全:PDF文档可设置为只读模式,并且可以添加密码等保护措施。 美…...

(接口测试)day01接口测试理论 http理论 接口测试流程 接口文档解析

一.接口测试理论 1.接口和接口测试 服务器为客户端开了一个验证接口(接口本质:函数方法)客户端向服务器传送的消息可以相当于函数的参数,接口是用来让客户端传递数据的 接口:相当于开了一个通道 当服务器要给客户端响…...

Telegram——Bot 机器人/小程序入门指南

一、Bot 介绍 在 TG 中,机器人可以用于接收和发送消息、管理群组(在有权限的情况下可以封禁用户、删除消息、置顶消息等)、通过API进行编程操作、使用 Inline 查询功能在不同的聊天室中提供查询服务、创建自定义键盘按钮、发出账单并收款、接入小程序游戏等。 然而,Bot 默…...

tauri build 后界面样式失效

其中一种情况:你为了使用 convertFileSrc 来加载本地资源,按照官方文档在 tauri.conf.json 中 设置了 tauri.security.csp 为 "default-src self; img-src self asset: https://asset. Localhost",恰好你在组件中编写了一部分的内联…...

打印自然常数E

自然常数E 自然常数,符号e,为数学中一个常数,是一个无限不循环小数,且为超越数,其值约为2.718281828459045。它是自然对数函数的底数。 我们打印表达式(11/x)的x次方的值以及获取第一次大于2.718的正整数 新建C#控制…...

澳鹏干货 | 大语言模型的上下文窗口 (Context Windows)

大语言模型(LLMs)极大地提升了人工智能在理解和生成文本方面的能力。其中一个影响其效用的重要方面是“上下文窗口”(Context Windows)—— 这个概念直接影响着模型接收和生成语言的有效性。 本期澳鹏干货将深入探讨上下文窗口对…...

为什么k8s不支持docker-kubernetes

为什么Kubernetes不再支持Docker? 在Kubernetes 1.20版本之后,Kubernetes宣布逐步停止对Docker作为容器运行时的支持。这一改变在容器管理领域引起了广泛关注。许多人不禁疑惑:Kubernetes与Docker一向密切合作,为何会做出这样的决…...

数据结构编程实践20讲(Python版)—17散列

本文目录 17 散列(Hashing)S1 说明特点应用领域S2 示例:字符串哈希S2 示例:文件、图片哈希S3 应用1:食品安全追溯S4 应用2:在线内容版权保护S5 应用3:社交媒体内容审核往期链接 01 数组02 链表03 栈04 队列05 二叉树06 二叉搜索树07 AVL树08 红黑树09 B树10 B+树11 线段…...

看了大厂用AI审简历,我才发现社会的残酷真相!今年的秋招太可怕了

太可怕了!今年秋招,大厂竟然引进黑科技—— AI 面试、AI 智能分析简历, 这让打工人以后咋敢写精通 Office 三件套,就怕被 AI 一眼识破 劝你现在掌握 AI 技能,真的不是说说而已! 微软的最新职场 AI 统计数…...

京东大模型革命电商搜推技术:挑战、实践与未来趋势

大模型对搜推技术产生了深远的影响,极大地推动了搜推技术的演进趋势,使得搜推更加的智能化和个性化,然而在搜推中引入大模型时同样面临一系列的挑战,例如商品知识的幻觉,复杂查询的理解,个性化商品推荐&…...

深入学习二叉树(BinaryTree)(纯小白进)

目录: 一、 前言二、 正文2.1、 树的概念2.1.1、 树的结构2.1.2、 树的小知识 2.2、 认识二叉树2.2.1、 二叉树的概念2.2.2、 特殊的二叉树 2.3、 实现二叉树2.3.1、 结构2.3.2、 节点数2.3.3、 树深度2.3.4、 前、中、后序遍历 销毁2.3.4.1、 前序遍历2.3.4.2、 中…...

诗风秦韵诗词学习画廊宣言

诗风秦韵诗词学习画廊宣言 弘扬传统传承文明,奋斗路上不断前进,青春不朽梦想扬帆,华夏赞歌我心飞扬...

Cannot determine local hostname

1. 问题与解答 报错: o.s.cloud.commons.util.InetUtils : Cannot determine local hostname 可能原因: 缺少一个logback.xml 2. logback日志文件介绍 2.1 logback结构与组成 logback.xml 文件是 Logback 的核心配置文件,其基本…...

电工课堂-对晶闸管移相控制触发要求

晶闸管移相控制触发的要求主要包括触发信号的同步性、移相范围、输出功率、触发脉冲的参数和形式等。 触发信号的同步性:触发信号必须与主电路的电源频率保持一致,并具有固定的相位关系。这是为了确保在每个周期内晶闸管都能在相同的相位上被触发&#x…...

基于Arduino做的“鱿鱼游戏”BOSS面具,支持动作检测

这是一个结合了3D打印、舵机、PIR传感器和DFPlayer MP3模块的DIY项目,旨在制作一个带有动画眼睛的"鱿鱼游戏"老板面具。当检测到动作时,面具的眼睛会移动并播放声音,非常适合万圣节使用。 这个项目是一个很好的起点,特…...

数据库的查询操作

之前学习了怎么创建数据库&#xff0c;创建数据表以及给数据表添加数据&#xff0c;我们今天就学习一下数据的查询 一. 查询语句的语法 select 列名&#xff08;字段名&#xff09; form 表名 [where &#xff08;查询条件表达式&#xff09;] [order by <排序的列明>[…...

LeetCode知识点总结 - 524

LeetCode 524. Longest Word in Dictionary through Deleting考点难度ArrayMedium题目 Given a string s and a string array dictionary, return the longest string in the dictionary that can be formed by deleting some of the given string characters. If there is mor…...

从零开始优化接口性能:QPS、TPS、OTPS、TP99的实战指南

从零开始优化接口性能&#xff1a;QPS、TPS、OTPS、TP99的实战指南 当你的电商系统在秒杀活动中突然崩溃&#xff0c;或是聊天机器人回复速度慢到用户流失时&#xff0c;性能指标就不再是枯燥的数字&#xff0c;而是决定业务存亡的关键。我曾经历过一次惨痛的教训&#xff1a;某…...

VeraCrypt实战指南:从取证入门到加密容器构建

1. VeraCrypt初探&#xff1a;数字取证中的"保险箱" 第一次接触VeraCrypt是在去年的网络安全竞赛上。当时有个加密容器文件摆在面前&#xff0c;队友急得直挠头&#xff1a;"这玩意儿怎么打开&#xff1f;"我盯着那个看似普通的文件&#xff0c;突然意识到…...

手把手教你用LVGL 8.x实现一个会变色的电池电量控件(附完整代码)

从零构建LVGL 8.x动态电池控件&#xff1a;变色逻辑与分辨率适配实战 在智能手表、医疗设备等嵌入式场景中&#xff0c;电池电量的可视化展示从来都不只是简单的数字堆砌。想象一下&#xff0c;当用户瞥见设备屏幕时&#xff0c;一个会随着电量降低逐渐由绿转红的电池图标&…...

ChatGLM-6B真实反馈:用户对话满意度调查结果分享

ChatGLM-6B真实反馈&#xff1a;用户对话满意度调查结果分享 1. 引言&#xff1a;一次真实的对话体验调查 最近&#xff0c;我们围绕ChatGLM-6B智能对话服务进行了一次小范围的用户满意度调查。这不是一份冷冰冰的技术评测报告&#xff0c;而是一次真实的对话体验分享。我们邀…...

matlab程序,傅里叶变换,频域数据,补零与不补零傅里叶变换

软件复制到浏览器下载&#xff1a;https://wwb.lanzouw.com/b02cila0j密码:cv10在导入数据前需明确是否勾选“加速度数据尾部补0,长度变为2的n次方”&#xff0c;如果输入数据点数是2 的整数倍&#xff0c;则可以直接使用 FFT 算法进行快速傅里叶变换&#xff0c;计算效率和变换…...

领域驱动设计实践:event-sourcing-examples中的DDD聚合模式

领域驱动设计实践&#xff1a;event-sourcing-examples中的DDD聚合模式 【免费下载链接】event-sourcing-examples Example code for my building and deploying microservices with event sourcing, CQRS and Docker presentation 项目地址: https://gitcode.com/gh_mirrors…...

OpenUSD终极渲染器切换指南:Storm vs Prman性能深度对比

OpenUSD终极渲染器切换指南&#xff1a;Storm vs Prman性能深度对比 【免费下载链接】OpenUSD Universal Scene Description 项目地址: https://gitcode.com/GitHub_Trending/ope/OpenUSD OpenUSD&#xff08;Universal Scene Description&#xff09;作为强大的3D场景描…...

LangChain实战:从零构建一个联网搜索增强的RAG问答系统

1. 为什么需要联网搜索增强的RAG系统 传统的RAG&#xff08;检索增强生成&#xff09;系统有个致命伤——它只能回答知识库里已有的内容。想象一下&#xff0c;你去年精心构建了一个旅游推荐系统&#xff0c;但今年新开的网红景点它完全不知道&#xff0c;因为数据没更新。这就…...

Java Spring Boot 中构造器循环依赖的处理

本文探讨了 Java Spring Boot 循环依赖问题是由于工程中结构设计不当造成的。通过分析示例代码&#xff0c;解释了循环依赖的原因&#xff0c;并提供了有效的解决方案来避免这些问题&#xff0c;重点是避免在结构中创建依赖对象的新例子&#xff0c;以防止无限递归调用 StackOv…...