RabbitMQ消息可靠性投递与ACK确认机制

1.RabbitMQ的消息可靠性投递

  • 什么是消息的可靠性投递
    • 保证消息百分百发送到消息队列中去
    • 保证MQ节点成功接收消息
    • 消息发送端需要接收到MQ服务端接收到消息的确认应答
    • 完善的消息补偿机制,发送失败的消息可以再感知并二次处理
  • RabbitMQ消息投递路径
    • 生产者–>交换机–>队列–>消费者
    • 通过两个节点控制消息的可靠性投递
      • 生产者到交换机:通过confirmCallback
      • 交换机到队列:通过returnCallback
  • 建议
    • 开启消息确认机制以后,保证了消息的准确送达,但由于频繁的确认交互,RabbitMQ整体效率变低,吞吐量下降严重,不是很重要的消息不建议使用消息确认机制

2.RabbitMQ消息可靠性投递confirmCallback实战

  • 生产者到交换机

    • 通过confirmCallback
    • 生产者投递消息后,如果Broker收到消息后,会给生产者一个ACK。生产者通过ACK可以确认这条消息是否正常发送到Broker,这种方式是消息可靠性投递的核心
  • 开启confirmCallback配置

    spring.rabbitmq.publisher-confirm-type=correlated
    
  • 消息发送测试

    package com.gen;
    
    import com.gen.config.RabbitMQConfig;
    import org.junit.jupiter.api.Test;
    import org.springframework.amqp.rabbit.core.RabbitTemplate;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    
    @SpringBootTest
    class GenRabbitmqApplicationTests {
    
        @Autowired
        private RabbitTemplate rabbitTemplate;
    
        @Test
        void testConfirmCallback() {
            this.rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
                System.out.println(correlationData);
                System.out.println(cause);
                if (ack) {
                    System.out.println("发送成功");
                } else {
                    System.out.println("发送失败");
                }
            });
            this.rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME, "order.new", "您有新订单!!!");
            // 模拟消息投递失败
    //        this.rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME+"1", "order.new", "您有新订单!!!");
        }
    }
    

3.RabbitMQ消息可靠性投递returnCallback实战

  • 交换机到队列

    • 通过returnCallback
    • 消息从交换机发送到对应队列失败时触发
    • 两种模式
      • 交换机到队列不成功,则丢弃消息(默认)
      • 交换机到队列不成功,返回给消息生产者,触发returnCallback
  • 配置文件开启配置

    # 开启returnCallback配置
    spring.rabbitmq.publisher-returns=true
    # 修改交换机投递到队列失败的策略,true交换机处理消息到路由失败会返回给生产者
    spring.rabbitmq.template.mandatory=true
    
  • 消息发送测试

    package com.gen;
    
    import com.gen.config.RabbitMQConfig;
    import org.junit.jupiter.api.Test;
    import org.springframework.amqp.rabbit.core.RabbitTemplate;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    
    @SpringBootTest
    class GenRabbitmqApplicationTests {
    
        @Autowired
        private RabbitTemplate rabbitTemplate;
    
        @Test
        void testReturnCallback() {
            this.rabbitTemplate.setReturnsCallback((returned) -> {
                System.out.println(returned);
            });
            this.rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME, "order.new", "您有新订单!!!");
            // 模拟消息转发队列失败
    //        this.rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME, "gen.order.new", "您有新订单!!!");
        }
    }
    

4.RabbitMQ消息确认机制ACK

  • 背景:消费者从Broker中监听消息,需要确保消息被合理处理

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • RabbitMQ的ACK介绍

    • 消费者从RabbitMQ收到消息并处理完成后,反馈给RabbitMQ,RabbitMQ收到反馈后才将此消息从队列中删除
    • 消费者在处理消息出现了网络不稳定、服务器异常等现象,那么就不会有ACK反馈,RabbitMQ会认为这个消息没有正常消费,会将消息重新放入队列中
    • 只有当消费者正确发送ACK反馈,RabbitMQ确认收到后,消息才会从RabbitMQ服务器的数据中删除
    • 消息的ACK确认机制默认是打开的,消息如未被进行ACK的消息确认机制,这条消息被锁定Unacked
  • 确认方式

    • 自动确认(默认)
    • 手动确认manual
  • 配置文件开启手动确认

    spring.rabbitmq.listener.simple.acknowledge-mode=manual
    
  • 消费者代码

    package com.gen.listener;
    
    import com.gen.config.RabbitMQConfig;
    import com.rabbitmq.client.Channel;
    import org.springframework.amqp.core.Message;
    import org.springframework.amqp.rabbit.annotation.RabbitHandler;
    import org.springframework.amqp.rabbit.annotation.RabbitListener;
    import org.springframework.stereotype.Component;
    
    import java.io.IOException;
    
    @Component
    @RabbitListener(queues = RabbitMQConfig.QUEUE_NAME)
    public class OrderMQListener {
    
        @RabbitHandler
        public void orderConsumer(String msg, Message message, Channel channel) throws IOException {
            System.out.println(msg);
            System.out.println(message);
            System.out.println(channel);
            long deliveryTag = message.getMessageProperties().getDeliveryTag();
            System.out.println(deliveryTag);
    
            // 成功确认,消费成功
            channel.basicAck(deliveryTag, false);
            // 拒绝后重新入队
    //        channel.basicNack(deliveryTag, false,true);
        }
    }
    
  • deliveryTag介绍:表示消息投递序号,每次消费消息或者消息重新投递后,deliveryTag都会增加

  • basicNack和basicReject介绍

    • basicReject一次只能拒绝接收一个消息,可以设置是否重新入队requeue
    • basicNack方法可以支持一次0个或者多个消息的拒收,可以设置是否重新入队requeue
  • 人工审核异常消息

    • 设置重试阈值,超过后确认消费成功,记录消息,人工处理
  • 9
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
方案是为解决特定问题或达成特定目标而制定的一系列计划或步骤。它的作用是提供一种系统性的方法,以有效地应对挑战、优化流程或实现目标。以下是方案的主要作用: 问题解决: 方案的核心目标是解决问题。通过系统性的规划和执行,方案能够分析问题的根本原因,提供可行的解决方案,并引导实施过程,确保问题得到合理解决。 目标达成: 方案通常与明确的目标相关联,它提供了一种达成这些目标的计划。无论是企业战略、项目管理还是个人发展,方案的制定都有助于明确目标并提供达成目标的路径。 资源优化: 方案在设计时考虑了可用资源,以最大化其效用。通过明智的资源分配,方案可以在有限的资源条件下实现最大的效益,提高效率并减少浪费。 风险管理: 方案通常会对潜在的风险进行评估,并制定相应的风险管理策略。这有助于减轻潜在问题的影响,提高方案的可行性和可持续性。 决策支持: 方案提供了决策者所需的信息和数据,以便做出明智的决策。这种数据驱动的方法有助于减少不确定性,提高决策的准确性。 团队协作: 复杂的问题通常需要多个人的协同努力。方案提供了一个共同的框架,帮助团队成员理解各自的职责和任务,促进协作并确保整个团队朝着共同的目标努力。 监控与评估: 方案通常包括监控和评估的机制,以确保实施的有效性。通过定期的评估,可以及时调整方案,以适应变化的环境或新的挑战。 总体而言,方案的作用在于提供一种有序、有计划的方法,以解决问题、实现目标,并在实施过程中最大化资源利用和风险管理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水宝的滚动歌词

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值