【RabbitMQ笔记08】消息队列RabbitMQ之防止消息丢失的三种方式(生产者消息确认、消费者消息确认、消息持久化)

这篇具有很好参考价值的文章主要介绍了【RabbitMQ笔记08】消息队列RabbitMQ之防止消息丢失的三种方式(生产者消息确认、消费者消息确认、消息持久化)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这篇文章,主要介绍消息队列RabbitMQ之防止消息丢失的三种方式(生产者消息确认、消费者消息确认、消息持久化)。

目录

一、防止消息丢失

1.1、消息确认机制(生产者)

(1)生产者丢失消息

(2)生产者消息确认机制

1.2、消息确认机制(消费者)

(1)消费者丢失消息

(2)消费者消息确认机制

1.3、消息持久化(RabbitMQ)

(1)RabbitMQ丢失消息

(2)消息持久化机制


一、防止消息丢失

RabbitMQ消息队列,在使用的时候,可能会存在消息丢失的情况,所谓的消息丢失就是生产者发送的消息没办法被消费者正确的消费,消息队列中导致消息丢失的地方有三个,分别是:

  • 第一种情况:生产者发送的消息没有正确的发送到RabbitMQ里面,导致发送的消息丢失。
  • 第二种情况:消费者从RabbitMQ消费消息时候,消费失败,但是RabbitMQ认为消费成功,从而删除了消息。
  • 第三种情况:RabbitMQ中保存的消息还没有被消费者消费,此时RabbitMQ服务宕机,导致内存中的消息丢失。

1.1、消息确认机制(生产者)

(1)生产者丢失消息

生产者丢失消息,是指:当生产者发送消息给RabbitMQ的时候,此时消息发送失败了,并且生产者又没有重新发送这一条消息,所以这个时候,生产者这一条失败的消息就丢失了。

既然是生产者发送消息失败导致这一条消息丢失的,那么我们在处理这个丢失消息问题的时候,就可以这样做:当生产者消息发送失败之后,可以让生产者再次发送这一条消息,这里就有一个问题啦,那就是生产者怎么知道消息有没有发送成功???

RabbitMQ给我们提供了一个机制,即:发布确认机制,大致思想是:当生产者将消息发送到RabbitMQ之后,并且RabbitMQ正确接收到消息并将其放入Queue队列里面时,RabbitMQ会返回一个ACK标识给生产者,生产者接收到ACK标识就可以认为消息发送成功啦;如果消息接收失败,RabbitMQ会返回一个NACK标识,表示接收失败。

消息队列如何保证消息不丢失,【中间件笔记】,rabbitmq,消息中间件,RabbitMQ消息队列,消息确认,消息持久化

(2)生产者消息确认机制

生产者消息确认机制,上一篇文章已经介绍了(【RabbitMQ笔记07】消息队列RabbitMQ七种模式之Publisher Confirms发布确认模式),这里就不再重复。

1.2、消息确认机制(消费者)

(1)消费者丢失消息

如果生产者已经将消息正确的发送到RabbitMQ里面了,消费者从Queue队列里面获取消息消费时候,如果消费失败,那么此时就会导致这一条消息丢失,这是因为,默认情况下,RabbitMQ将消息分发给消费者之后,消费者接收到消息时候,就会返回一个ACK标识给消息队列RabbitMQ,此时RabbitMQ就会将这一条消息从Queue队列里面删除,但是这种情况下,消费者是否正确将这条消息消费了,RabbitMQ是不知道的,所以这就有可能导致丢失。

如何解决消费者丢失消息???

  • 既然丢失消息是因为消费者消费失败,并且RabbitMQ把消息删除了,那么我们就可以开启手动确认的方式来告诉RabbitMQ,消费者是否正确的消费消息,是否可以将消息从Queue队列里面删除了。

消息队列如何保证消息不丢失,【中间件笔记】,rabbitmq,消息中间件,RabbitMQ消息队列,消息确认,消息持久化

(2)消费者消息确认机制

  • 消费者进行消息确认,需要关闭自动确认,将【basicConsume()】方法的第二个参数设置为【false】。
  • 消息成功消费之后,主动调用【basicAck()】方法,返回ACK标识给RabbitMQ。
package com.rabbitmq.demo.dropmsg;

import com.rabbitmq.client.*;

import java.io.IOException;

/**
 * @version 1.0.0
 * @Date: 2023/2/25 16:30
 * @Copyright (C) ZhuYouBin
 * @Description: 消息消费者
 */
public class Consumer {
    public static void main(String[] args) {
        // 1、创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        // 2、设置连接的 RabbitMQ 服务地址
        factory.setHost("127.0.0.1"); // 默认就是本机
        factory.setPort(5672); // 默认就是 5672 端口
        // 3、获取连接
        Connection connection = null; // 连接
        Channel channel = null; // 通道
        try {
            connection = factory.newConnection();
            // 4、获取通道
            channel = connection.createChannel();
            // 5、声明 Exchange,如果不存在,则会创建
            String exchangeName = "exchange_dropmsg_2023";
            channel.exchangeDeclare(exchangeName, "direct");
            // 6、指定需要操作的消息队列,如果队列不存在,则会创建
            String queueName = "queue_dropmsg_2023";
            channel.queueDeclare(queueName, false, false, false, null);
            // 7、绑定 Exchange 和 Queue, 接收 routingKey = "info" 的消息
            channel.queueBind(queueName, exchangeName, "key_2023");
            // 8、消费消息
            Channel finalChannel = channel;
            DeliverCallback callback = new DeliverCallback() {
                public void handle(String s, Delivery delivery) throws IOException {
                    // 接收消息
                    System.out.println("这是接收的消息:" + new String(delivery.getBody()));
                    // TODO 消费者正确消费消息之后,主动返回 ACK 标识
                    finalChannel.basicAck(delivery.getEnvelope().getDeliveryTag(), true);
                }
            };
            // TODO 这第二个参数修改为 false,表示消费者需要手动发送 ACK 标识给 RabbitMQ(默认是true)
            channel.basicConsume(queueName, false, callback, i->{});
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

1.3、消息持久化(RabbitMQ)

(1)RabbitMQ丢失消息

上面介绍了两种丢失消息的情况,分别是生产者和消费者丢失消息,还有一种丢失消息的情况,那就是RabbitMQ消息队列将消息丢失了。假设,现在存在这一种情况,生产者已经正确将消息发送到RabbitMQ里面,正准备将消息发送给消费者的时候,此时RabbitMQ服务宕机了,导致RabbitMQ中的消息丢失了(默认情况下,RabbitMQ是将消息保存在内存中的),由于内存中的数据断电即失,所以这就导致消息丢失情况。

如何解决RabbitMQ出现的消息丢失问题呢???

  • 既然RabbitMQ是将消息保存在内存中的,那么为了避免消息丢失,可以将内存中的消息保存到磁盘文件里面,这样即使RabbitMQ宕机了,重新启动的时候也可以从磁盘文件里面读取消息到内存里面。

消息队列如何保证消息不丢失,【中间件笔记】,rabbitmq,消息中间件,RabbitMQ消息队列,消息确认,消息持久化

(2)消息持久化机制

  • 在调用【queueDeclare()】方法,创建Queue队列的时候,设置第二个参数等于【true】,表示消息允许持久化。
  • 生产者调用【basicPublish()】方法发送消息的时候,设置消息属性等于【MessageProperties.PERSISTENT_TEXT_PLAIN】,表示文本持久化。
// 第二个参数设置为true,表示开启持久化消息
channel.queueDeclare("Queue队列名称", true, false, false, null);

// 生产者发送消息时候,设置消息属性是文本持久化
channel.basicPublish("Exchange交换机名称", "Queue队列名称", MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());

到此,RabbitMQ消息队列防止消息丢失的三种方式介绍完啦。

综上,这篇文章结束了,主要介绍消息队列RabbitMQ之防止消息丢失的三种方式(生产者消息确认、消费者消息确认、消息持久化)。文章来源地址https://www.toymoban.com/news/detail-787896.html

到了这里,关于【RabbitMQ笔记08】消息队列RabbitMQ之防止消息丢失的三种方式(生产者消息确认、消费者消息确认、消息持久化)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【SpringBoot笔记29】SpringBoot集成RabbitMQ消息队列

    这篇文章,主要介绍SpringBoot如何集成RabbitMQ消息队列。 目录 一、集成RabbitMQ 1.1、引入amqp依赖 1.2、添加连接信息 1.3、添加RabbitMQ配置类

    2023年04月08日
    浏览(56)
  • 防止消息丢失与消息重复——Kafka可靠性分析及优化实践

    上手第一关,手把手教你安装kafka与可视化工具kafka-eagle Kafka是什么,以及如何使用SpringBoot对接Kafka 架构必备能力——kafka的选型对比及应用场景 Kafka存取原理与实现分析,打破面试难关 在上一章内容中,我们解析了Kafka在读写层面上的原理,介绍了很多Kafka在读出与写入时的

    2024年02月08日
    浏览(44)
  • Elasticsearch 8.X 防止 Mapping “爆炸”的三种方案

    Elasticsearch 映射如果不做特殊处理,默认 dynamic 为 true。dynamic 为 true 的确切含义是:根据导入的数据自定识别字段类型(有可能不精确),也就是说,可以提前不指定 Mapping,也能写入数据。 但,这导致的问题也非常明显。Mapping 字段越多,会超过默认字段数上限。超过上限

    2023年04月19日
    浏览(37)
  • 思科IOS防止遭受IP地址欺骗攻击的三种办法

    IP欺骗技术就是伪造某台主机的IP 地址的技术。通过IP地址的伪装使得某台主机能够伪装另外的一台主机,而这台主机往往具有某种特权或者被另外的主机所信任。在一次典型的地址欺骗尝试中,攻击者只是简单地伪装源数据包使其看起来是内自于内部网络。下面谈一下怎样利

    2024年02月07日
    浏览(45)
  • RabbitMQ学习笔记(消息发布确认,死信队列,集群,交换机,持久化,生产者、消费者)

    MQ(message queue):本质上是个队列,遵循FIFO原则,队列中存放的是message,是一种跨进程的通信机制,用于上下游传递消息。MQ提供“逻辑解耦+物理解耦”的消息通信服务。使用了MQ之后消息发送上游只需要依赖MQ,不需要依赖其它服务。 功能1:流量消峰 功能2:应用解耦 功

    2024年02月07日
    浏览(54)
  • RabbitMQ 消息丢失的场景,如何保证消息不丢失?

    第一种:生产者弄丢了数据。生产者将数据发送到 RabbitMQ 的时候,可能数据就在半路给搞丢了,因为网络问题啥的,都有可能。 第二种:RabbitMQ 弄丢了数据。MQ还没有持久化自己挂了 第三种:消费端弄丢了数据。刚消费到,还没处理,结果进程挂了,比如重启了。 1.针对生

    2024年02月11日
    浏览(53)
  • RabbitMQ消息丢失的场景,MQ消息丢失解决方案

    第一种 : (生产者) 生产者弄丢了数据。生产者将数据发送到 RabbitMQ 的时候,可能数据就在半路给搞丢了,因为网络问题啥的,都有可能。 第二种 : (服务端) RabbitMQ 弄丢了数据。MQ还没有持久化自己挂了 第三种 : (消费者) 消费端弄丢了数据。刚消费到,还没处理

    2024年02月08日
    浏览(50)
  • RabbitMQ防止消息重复消费、保证异步消息的幂等性

    一、rabbitmq出现消息重复的场景 1、消费成功,没有进行ack,这时 Broker 会重新发送 2、不确认(unack)或 reject 之后,重新排队,Broker 会重新发送 3、消费成功,ack时宕机,没有ack成功,消息由unack变为ready,Broker又重新发送 4、总的来说就是 Broker 发送消息后,消费端收到消息

    2024年02月13日
    浏览(45)
  • (五)RabbitMQ-进阶 死信队列、延迟队列、防丢失机制

    Lison dreamlison@163.com , v1.0.0 , 2023.06.23 概念 在MQ中,当消息成为死信(Dead message)后,消息中间件可以 将其从当前队列发送到另一个队列中,这个队列就是死信队列。而 在RabbitMQ中,由于有交换机的概念,实际是将死信发送给了死 信交换机(Dead Letter Exchange,简称DLX)。死信交

    2024年02月15日
    浏览(54)
  • RabbitMQ如何避免丢失消息

    消息从生产到消费,要经历三个阶段,分别是生产、队列转发与消费,每个环节都可能丢失消息。 以下以RabbitMQ为例,来说明各个阶段会产生的问题以及解决方式。在说明之前,先回顾一下RabbitMQ的一个基本架构图 1. 网络问题 外界环境问题导致:发生网络丢包、网络故障等造

    2024年02月10日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包