0

    RabbitMQ的几种消息确认机制详细介绍

    2023.04.26 | admin | 225次围观

    前言:大家好,我是小威,24届毕业生,在一家满意的公司实习。本篇文章将详细介绍RabbitMQ的几种消息确认机制。

    如果文章有什么需要改进的地方还请大佬不吝赐教。

    小威在此先感谢各位大佬啦~~

    个人主页:小威要向诸佬学习呀

    个人简介:大家好,我是小威,一个想要与大家共同进步的男人

    目前状况:24届毕业生,在一家满意的公司实习

    欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,我亲爱的大佬

    以下正文开始

    文章目录

    RabbitMQ的消息确认机制

    RabbitMQ消息确认机制指的是在消息传递过程中,发送方发送消息后,接收方需要对消息进行确认,以确保消息被正确地接收和处理。RabbitMQ的消息确认机制分为两种:

    生产者确认机制:生产者发送消息后,需要等待RabbitMQ服务器的确认消息,以确保消息已经被成功地发送到RabbitMQ服务器。如果RabbitMQ服务器没有收到消息或者消息发送失败,生产者会收到一个确认消息,从而可以进行重发或者其他处理。

    消费者确认机制:消费者接收到消息后,需要向RabbitMQ服务器发送确认消息,以告诉服务器已经成功地接收并处理了该消息。如果消费者没有发送确认消息,RabbitMQ服务器会认为该消息没有被正确地处理,从而会将该消息重新发送给其他消费者进行处理。

    在RabbitMQ中,消息确认机制是通过ACK机制来实现的。ACK代表Acknowledgement,即确认消息。当消息发送方发送消息后,接收方需要向消息发送方发送ACK消息,以表示已经成功地接收和处理了该消息。如果消息发送方没有收到ACK消息,就会认为该消息没有被正确地处理,从而进行重发或者其他处理。

    总之,RabbitMQ的消息确认机制可以保证消息的可靠性,从而提高系统的稳定性和可靠性。

    消息可靠抵达-ConfirmCallback

    RabbitMQ的消息确认机制确保了消息的可靠抵达,其中ConfirmCallback是其中一种实现方式。

    ConfirmCallback是一个回调函数,用于在消息被确认时进行回调,以确保消息已经被正确地发送到RabbitMQ Broker并被处理。当生产者发送消息时,可以通过调用channel的confirmSelect()方法将channel设置为confirm模式,然后通过添加ConfirmCallback回调函数来处理消息确认。

    当消息被发送到Broker后,如果Broker成功地将消息路由到目标队列,则会调用ConfirmCallback回调函数的handleAck()方法,表示消息已被确认。如果Broker无法将消息路由到目标队列,则会调用handleNack()方法,表示消息未被确认。

    使用ConfirmCallback可以确保消息已经被正确地发送到RabbitMQ Broker并被处理接收服务器消息回调url失败,从而避免了消息丢失或重复发送的情况。同时,ConfirmCallback还可以在消息未被确认时进行重试或记录日志等操作,以确保消息的可靠性和稳定性。

    ConfirmCallback使用说明:

    在配置文件中配置:spring.rabbitmq.publisher-confirms=true

    在创建 connectionFactory 的时候设置 PublisherConfirms(true) 选项,开启

    confirmcallback 。

    CorrelationData:用来表示当前消息唯一性。

    消息只要被 broker 接收到就会执行 confirmCallback,如果是 cluster 模式,需要所有broker 接收到才会调用 confirmCallback。

    被 broker 接收到只能表示 message 已经到达服务器,并不能保证消息一定会被投递 到目标 queue 里。所以需要用到接下来的 returnCallback 。

    消息可靠抵达-ReturnCallback

    RabbitMQ的ReturnCallback机制是为了解决消息无法路由到指定队列的问题。当发送的消息无法被路由到指定队列时,RabbitMQ会将消息返回给生产者,这时候如果生产者设置了ReturnCallback回调函数,就可以在回调函数中处理这种情况。

    ReturnCallback机制的使用场景一般是在消息发送时,指定了mandatory参数为true,表示如果消息无法被路由到指定队列,则将消息返回给生产者。如果mandatory参数为false,则消息会被直接丢弃。

    当生产者设置了ReturnCallback回调函数后,RabbitMQ在将消息返回给生产者时,会触发该回调函数。在ReturnCallback回调函数中,可以处理消息无法路由的情况,例如重发消息、记录日志等。

    下面是一个使用ReturnCallback机制的示例代码:

    channel.addReturnListener(new ReturnCallback() {
        @Override
        public void handle(ReturnedMessage returnedMessage) {
            String message = new String(returnedMessage.getBody());
            System.out.println("Message returned: " + message);
        }
    });
    channel.basicPublish(exchangeName, routingKey, true, null, message.getBytes());
    

    在上面的代码中,我们通过addReturnListener方法设置了ReturnCallback回调函数,当消息无法路由到指定队列时,会触发该回调函数。在回调函数中,我们将返回的消息打印出来,以便处理。

    需要注意的是,ReturnCallback机制只有在消息被发送到交换机后,才会触发。如果消息发送的交换机不存在,或者路由键不符合任何绑定规则,消息会被直接丢弃,不会触发ReturnCallback回调函数。

    在配置文件中配置:

    spring.rabbitmq.publisher-returns=true
    spring.rabbitmq.template.mandatory=true
    

    confrim 模式只能保证消息到达 broker,不能保证消息准确投递到目标 queue 里。在有 些业务场景下,我们需要保证消息一定要投递到目标 queue 里,此时就需要用到return 退回模式。

    这样如果未能投递到目标 queue 里将调用 returnCallback ,可以记录下详细到投递数据,定期的巡检或者自动纠错都需要这些数据。

    RabbitMQ自动确认和手动确认

    RabbitMQ消息确认机制是一种保证消息可靠抵达的机制。在RabbitMQ中,消息确认机制分为两种模式:自动确认模式和手动确认模式。

    在自动确认模式下,当消费者收到消息并将其处理完毕后,RabbitMQ会自动将该消息标记为已确认,然后将其从队列中删除。这种模式比较简单,但是存在消息丢失的风险,因为如果消费者在处理消息的过程中出现异常,消息就会被丢失。

    在手动确认模式下,当消费者收到消息并将其处理完毕后,需要向RabbitMQ发送一个确认消息,告诉RabbitMQ该消息已经被处理完毕,可以从队列中删除。如果消费者在处理消息的过程中出现异常,可以选择不发送确认消息,这样消息就不会被从队列中删除,可以重新被其他消费者获取。

    手动确认模式可以保证消息不会被丢失,但是需要消费者编写额外的代码来处理确认消息的发送。此外,手动确认模式还可以设置确认模式为批量确认模式,即一次性确认多个消息,可以提高消息处理的效率。

    总结:

    自动ACK模式

    在自动ACK模式下,消息一旦被消费者接收到,就会自动被确认。这种模式下,消息一旦被发送到消费者接收服务器消息回调url失败,就会从队列中删除,无论消费者是否已经成功消费该消息。

    手动ACK模式

    在手动ACK模式下,消费者必须手动发送ACK消息来确认消息已经被成功消费。如果消费者没有发送ACK消息,RabbitMQ服务器就会认为该消息还没有被消费,会将该消息重新发送给其他消费者。这种模式下,消费者可以选择性地确认消息,只有当消费者成功消费一条消息并确认后,该消息才会从队列中删除。

    手动ACK模式可以保证消息的可靠性,但是需要消费者在处理消息时进行额外的处理,消费者需要在处理消息后发送ACK消息,否则消息会被重新发送。

    在 RabbitMQ 中,消费者可以通过设置 channel.basicAck(deliveryTag, multiple) 方法来发送 ack 消息。其中,deliveryTag 表示消息的唯一标识符,multiple 表示是否批量确认。如果 multiple 为 true,表示要确认该 deliveryTag 及其之前的所有消息;如果 multiple 为 false,表示只确认该 deliveryTag 指定的一条消息。

    需要注意的是,如果消费者在处理消息时发生了异常,消息并没有被成功处理,那么不应该发送 ack 消息,而应该将消息重新放回队列中,让其他消费者来处理。

    RabbitMQ处理消息方法

    RabbitMQ提供了一些基本的方法来处理消息,这些方法包括:

    basic.publish: 发布消息到指定的交换机上。basic.consume: 消费消息,启动一个消费者来监听指定队列上的消息。basic.ack: 确认消息已经被消费,告诉RabbitMQ可以删除该消息。basic.nack: 否认消息已经被消费,告诉RabbitMQ需要重新发送该消息。basic.reject: 拒绝消息,告诉RabbitMQ不需要再次发送该消息。basic.get: 获取指定队列上的一条消息。basic.cancel: 取消消费者的消费,停止监听指定队列上的消息。

    这些方法都是基于AMQP协议定义的,可以使用RabbitMQ提供的客户端库或者自己实现AMQP协议来调用这些方法。

    图书推荐

    本期图书推荐为《Python大学教程》

    学习Python方向的大佬可以看下~

    该书籍有丰富的案例研究,练习题和项目,自我测评题,是一本良好的,值得阅读的书籍。

    当当书店购买链接:点击购买书籍

    粉丝福利:评论区任意留言可参与活动抽奖(可评论最多五条,抽取四名欧皇)

    好了,本篇文章就先分享到这里了,后续会继续分享其他方面的知识,感谢大佬认真读完支持咯~

    文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起讨论

    希望能和诸佬们一起努力,今后我们顶峰相见

    再次感谢各位小伙伴儿们的支持

    版权声明

    本文仅代表作者观点。
    本文系作者授权发表,未经许可,不得转载。

    发表评论