如何避免RabbitMQ消息丢失?

简介: 本文探讨了RabbitMQ中如何避免消息丢失的问题。在默认情况下,RabbitMQ并不保证消息的持久性,但提供了多种机制来确保消息的可靠传输与处理。文章分析了消息可能丢失的关键环节,并介绍了相应的保证机制:发布者确认交换机已接收消息、确认队列接收消息、队列及消息的持久化,以及消费者成功处理消息后的确认。通过Java代码示例展示了如何在实际应用中实现这些机制。最终,确保了消息在从生产到消费的整个流程中的可靠性。

前言

面试经常会被问到“怎么避免RabbitMQ消息不丢失”。首先需要明确的是,RabbitMQ在默认情况并不会保证消息的不丢失。不过RabbitMQ提供了一些机制,可以有效的避免消息在传输和处理过程中不丢失。

可能导致消息丢失的环节

先通过RabbitMQ的架构模型看一下消息的处理过程:

  1. 发布者和RabbitMQ建立连接发送消息至交换机。
  2. 交换机和队列绑定,将消息路由到队列中。
  3. 消费者和RabbitMQ建立连接指定某个队列的消息进行消费。

在这过程中以下几个环节可能会丢失消息:

  1. 发布者到交换机环节。
  2. 交换机到队列环节。
  3. 队列到消费者环节。

如下图

RabbitMQ的保证机制

很显然,在这样的处理过程中,要保证消息不丢失需要做到以下几点:

  1. 发布者需确认交换机接收到消息。
  2. 发布者需确认队列接收到消息。
  3. 保证队列及其中的数据持久化。
  4. 确保消费者的成功消费。

如何做到以上几点?

RabbitMQ为了适应各个场景的使用,以上的功能需要开发者按照定义自行设置。

Java代码示例

下面以Java为例,看一下在代码中如何进行相关设置。

确认Exchange接收到消息

在构建channel时添加确认机制,通过确认机制可以得知Exchange是否接收到消息,当消息未发送至Exchange时可以进行补偿措施。

java

代码解读

复制代码

 channel.addConfirmListener((sequenceNumber, multiple) -> {
            System.out.println("消息成功发送到交换机");
        }, (sequenceNumber, multiple) -> {
            System.err.println("消息未发送到交换机,补偿操作。");
        });

确认Queue接收到消息

  1. 构建channel时添加return机制,通过return机制可以得知Queue是否接收到消息,当消息未路由至Queue时可以进行补偿措施。

java

代码解读

复制代码

channel.addReturnListener((replyCode, replyText, exchange, routingKey, basicProperties, body) -> {
            System.err.format("消息 %s 未路由到指定队列: %s, replyText: %s,replyCode: %d%n", body, routingKey, replyText, replyCode);
        });
  1. 发布消息时设置消息mandatory为true,开启return机制。

java

代码解读

复制代码

 channel.basicPublish("", "",true, "", "");

保证Queue及其数据持久化

  1. 声明队列时设置队列持久化。默认情况下,通过channel.queueDeclare声明的队列是非持久的,这意味着如果RabbitMQ服务器重启,该队列所有未处理的消息都会丢失。

java

代码解读

复制代码

 //构建队列,queueDeclare("队列名称","是否持久化队列","是否只允许一个队列消费","长时间未使用是否删除","其他参数")
  channel.queueDeclare("", true, false, false, null);
  1. 还需要确保发布的消息也是持久化的,deliveryMode值为2意味着消息持久化。

java

代码解读

复制代码

//设置消息持久化
AMQP.BasicProperties basicProperties = new AMQP.BasicProperties.Builder().deliveryMode(2).build();
channel.basicPublish("", "",true, basicProperties, "");     

确定消费者的成功消费

当消息持久化至队列时,RabbitMQ已经保证了消息的可靠投递。

但是,为确保消费者的成功消费,消费端的确认机制通常被设置为手动确认模式,当消费者成功消费后向RabbitMQ发送确认信号,RabbitMQ才会从队列中删除该消息。

java

代码解读

复制代码

DeliverCallback deliverCallback = (consumerTag, delivery) -> {
            String message = new String(delivery.getBody(), "UTF-8");
            //消息处理后手动ACK
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
        };
// ack为false
channel.basicConsume("", false, deliverCallback, consumerTag -> {
});

总结

消息不丢失对于消息中间件来说是至关重要的,RabbitMQ通过消息的持久化、生产者确认、消费者确认等机制,有效地确保了消息的可靠性,避免了消息的丢失。


转载来源:https://juejin.cn/post/7347251816616919090

相关实践学习
快速体验阿里云云消息队列RocketMQ版
本实验将带您快速体验使用云消息队列RocketMQ版Serverless系列实例进行获取接入点、创建Topic、创建订阅组、收发消息、查看消息轨迹和仪表盘。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
消息中间件
RabbitMQ-如何保证消息不丢失
在RabbitMQ中,可以通过以下几种方式来保证消息不丢失:
805 0
|
前端开发 开发工具 Android开发
跨平台开发工具
跨平台开发工具
566 6
|
前端开发 JavaScript 测试技术
android做中大型项目完美的架构模式是什么?是MVVM吗?如果不是,是什么?
在 Android 开发中,选择合适的架构模式对于构建中大型项目至关重要。常见的架构模式有 MVVM、MVP、MVI、Clean Architecture 和 Flux/Redux。每种模式都有其优缺点和适用场景,例如 MVVM 适用于复杂 UI 状态和频繁更新,而 Clean Architecture 适合大型项目和多平台开发。选择合适的架构应考虑项目需求、团队熟悉度和可维护性。
364 6
|
6月前
|
IDE API 开发工具
鸿蒙开发:DevEcoStudio中那些实用的小功能
本篇文章就暂时给大家盘点四个,在后续的文章中,关于DevEco Studio中能够提升我们开发效率的功能,也会不间断的进行总结。
192 12
鸿蒙开发:DevEcoStudio中那些实用的小功能
|
人工智能 数据处理 计算机视觉
AI计算机视觉笔记十六:yolov5训练自己的数据集
本文介绍了一种利用云服务器AutoDL训练疲劳驾驶行为检测模型的方法。由于使用本地CPU训练效率低下,作者选择了性价比高的AutoDL云服务器。首先,从网络获取了2000多张疲劳驾驶行为图片并使用labelimg软件进行标注。接着,详细介绍了在云服务器上创建实例、上传数据集和YOLOv5模型、修改配置文件以及开始训练的具体步骤。整个训练过程耗时约3小时,最终生成了可用于检测的模型文件。
|
Prometheus 监控 Cloud Native
Nacos集群监控搭建
Nacos 0.8.0版本完善了监控系统,支持通过暴露metrics数据接入第三方监控系统监控Nacos运行状态。
331 1
|
存储 安全 前端开发
开发一款轻量级的chat app,需要准备什么?
本文探讨了开发轻量级Chat App的准备工作,包括需求分析、技术选型、设计规划和测试部署。需求分析涉及快速注册登录、实时聊天、好友管理、聊天室管理和隐私安全功能。技术选型推荐React Native或Flutter作为前端框架,Node.js或Spring Boot为后端,并考虑云服务部署。设计规划涵盖界面、交互和数据库设计。测试部署包括单元测试、集成测试、性能测试、兼容性测试以及上线计划和应急预案,以保证应用质量和稳定性。【6月更文挑战第8天】
438 1
|
安全 Go 网络安全
【Go语言专栏】Go语言中的HTTPS与TLS配置
【4月更文挑战第30天】本文介绍了在Go语言中配置HTTPS服务器和处理TLS证书的方法。首先,TLS证书由证书颁发机构(CA)颁发,用于验证服务器身份和加密通信。接着,展示了如何使用`crypto/tls`包加载自签名证书启动HTTPS服务器。在生产环境中,通常使用CA签名的证书,这需要获取证书链和私钥。为了自动续期证书,可以利用Go的`acme/autocert`包与ACME服务交互。掌握这些技能对于确保Web服务的安全至关重要。
1104 0
|
机器学习/深度学习 传感器 语音技术
毕业设计|基于STM32单片机的语音识别控制智能停车场设计
毕业设计|基于STM32单片机的语音识别控制智能停车场设计
679 0