【RabbitMQ】如何保证消息的可靠性传输,数据不丢失?

本文分析了RabbitMQ中消息丢失的三种情况,并详细介绍了如何保证消息的可靠性传输:通过生产者角度的事务机制、发送方确认机制,以及RabbitMQ的持久化设置。同时,讨论了消费者角度的自动确认与手动确认的差异,强调持久化与镜像队列在高可用性中的作用。
摘要由CSDN通过智能技术生成

目录

 

一、消息丢失的情况

1. 生产者——RabbitMQ:

2. RabbitMQ:

3. RabbitMQ——消费者:

二、如何保证消息的可靠性传输?

1.生产者角度

a. 事务机制

b. 发送方确认(publisher confirm)机制

2. RabbitMQ-持久化

3.消费者


一、消息丢失的情况

1. 生产者——RabbitMQ:

当消息的生产者将消息发送出去之后,消息到底有没有正确地到达服务器呢?

如果不进行特殊配置,默认情况下发送消息的操作是不会返回任何信息给生产者的,也就是默认情况下生产者是不知道消息有没有正确地到达服务器。如果在消息到达服务器之前己经丢了。

或者由于消息到了RabbitMQ但是内部出错了没有保存下来;

2. RabbitMQ:

RabbitMQ接受到消息之后就先暂存在自己的内存里,结果消费者还没有来得消费,RabbitMQ自己就挂掉了,就导致内存里面的数据丢失了

3. RabbitMQ——消费者:

消费者消费到了这个消息,但是还没来得及处理,自己就挂了,但是RabbitMQ以为这个消费者处理完了。

二、如何保证消息的可靠性传输?

针对第一种情况有如下解决方法:

1.生产者角度

RabbitMQ针这个问题,提供了两种解决方式:

  1. 通过事务机制实现
  2. 通过发送方确认(publisher confirm)机制实现

a. 事务机制

RabbitMQ客户端中与事务机制相关的方法有三个:

  • channel.txSelect用于将当前信道设置成事务模式
  • channel.txCommit用于提交事务
  • channel.txRollback用于事务回滚

       在通过channel.txSelect方法开启事务之后,我们便可以发布消息给RabbitMQ(这里是指交换器)了,如果事务提交成功,则消息一定到达了RabbitMQ中,如果在事务提交执行之前由于RabbitMQ异常崩溃或者其他原因抛出异常,这个时候我们便可以将其捕获,进而通过执行channel.txRollback方法来实现事务回滚。注意这里的RabbitMQ中的事务机制与大多数数据库中的事务概念井不相同,需要注意区分。

       try{
            channel.txSelect();
            channel.basicPublish("exchangeName","routeKey",props,"message".getBytes());
            channel.txCommit();
        }catch (Exception e){
            e.printStackTrace();
            channel.txRollback();
        }

如果需要发送多条消息,可以通过如下方式提交:

        channel.txSelect();
        for (int i=0;i<100;i++){
            try{
                channel.basicPublish("exchangeName","routeKey",props,"message".getBytes());
                channel.txCommit();
            }catch (Exception e){
                e.printStackTrace();
                channel.txRollback();
            }
        }

事务确实能够解决消息发送方和RabbitMQ之间消息确认的问题,只有消息成功被RabbitMQ接收,事务才能提交成功,否则便可在捕获异常之后进行事务回滚,与此同时可以进行消息重发。

但是使用事务机制会"吸干"RabbitMQ的性能,那么有没有更好的方法既能保证消息发送方确认消息已经正确送达,又能基本上不带来性能上的损失呢?从AMQP协议层面来看并没有更好的办法,但是RabbitMQ提供了一个改进方案&#x

RabbitMQ 作为一款开源的消息队列系统,为了保证消息的可靠传输和处理,采用了以下几个关键机制: 1. **确认机制(Acknowledgements)**:当消费者成功接收到消息后,会向 RabbitMQ 中心节点发送一个确认,如果中心节点没有收到确认,会重新将消息放入队列等待消费者的再次处理,直到超时或达到重试次数。 2. **持久化(Persistence)**:RabbitMQ 可以将消息写入磁盘,即使服务器宕机也能保证数据丢失,恢复后可以从上次的位置继续处理。 3. **事务(Transactions)**:对于需要原子性的操作,RabbitMQ 支持 AMQP 协议中的事务模式,确保一系列消息要么全部发送成功,要么全部失败并回滚。 4. **死信队列(Dead Letter Exchange)**:如果消息在长时间内无人消费或者多次重试失败,会被路由到死信队列,这样可以避免无限循环的情况,并提供一种人工干预处理异常的方式。 5. **镜像(Clustering and Mirroring)**:RabbitMQ 集群部署可提供高可用性和故障转移功能,即使某个节点失效,消息也可以被其他节点接管,保证服务不间断。 6. **幂等性(Idempotency)**:RabbitMQ 提供了消息路由和路由键的概念,同一个消息多次投递会产生相同的效果,避免了重复处理。 相关问题-- 1. RabbitMQ如何处理消息丢失的情况? 2. 什么情况下会触发死信队列? 3. 在RabbitMQ集群中,如何实现负载均衡和故障切换?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值