RabbitMQ【消息的可靠性投递(概念、确认模式、退回模式、Ack)】(六)-全面详解(学习总结---从入门到深化)

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

目录

消息的可靠性投递_概念

消息的可靠性投递_确认模式 

消息的可靠性投递_退回模式 

消息的可靠性投递_Ack 


消息的可靠性投递_概念

RabbitMQ【消息的可靠性投递(概念、确认模式、退回模式、Ack)】(六)-全面详解(学习总结---从入门到深化)_回调方法

RabbitMQ消息投递的路径为:

生产者 ---> 交换机 ---> 队列 ---> 消费者 

在RabbitMQ工作的过程中,每个环节消息都可能传递失败,那么 RabbitMQ是如何监听消息是否成功投递的呢? 

确认模式(confirm)可以监听消息是否从生产者成功传递到交换机。

退回模式(return)可以监听消息是否从交换机成功传递到队列。

消费者消息确认(Consumer Ack)可以监听消费者是否成功处理消息。 

首先我们准备两个SpringBoot项目,分别代表生产者和消费者,配置文件如下: 

spring:
 rabbitmq:
   host: 192.168.0.162
   port: 5672
   username: itxiaotong
   password: itxiaotong
   virtual-host: /
  
#日志格式
logging:
 pattern:
   console: '%d{HH:mm:ss.SSS} %clr(%-5level) --- [%-15thread] %cyan(%-50logger{50}):%msg%n'

 在生产者的配置类创建交换机和队列

@Configuration
public class RabbitConfig {
    private final String EXCHANGE_NAME="my_topic_exchange";
    private final String QUEUE_NAME="my_queue";
    // 1.创建交换机
    @Bean("bootExchange")
    public Exchange getExchange(){
        return ExchangeBuilder
               .topicExchange(EXCHANGE_NAME) // 交换机类型
               .durable(true) // 是否持久化
               .build();
   }
    // 2.创建队列
    @Bean("bootQueue")
    public Queue getMessageQueue(){
        return QueueBuilder
               .durable(QUEUE_NAME) // 队列持久化
               .build();
   }
    // 3.将队列绑定到交换机
    @Bean
    public Binding bindMessageQueue(@Qualifier("bootExchange") Exchange exchange, @Qualifier("bootQueue") Queue queue){
        return BindingBuilder.bind(queue).to(exchange).with("my_routing").noargs();
   }
}

实时效果反馈

1. 在RabbitMQ中,可以监听消息是否从生产者成功传递到交换机

A confirm

B return

C Ack

D 以上说法都不对


2. 在RabbitMQ中,可以监听消费者是否成功处理消息

A confirm

B return

C Ack

D 以上说法都不对

消息的可靠性投递_确认模式 

RabbitMQ【消息的可靠性投递(概念、确认模式、退回模式、Ack)】(六)-全面详解(学习总结---从入门到深化)_分布式_02

确认模式(confirm)可以监听消息是否从生产者成功传递到交换机,使用方法如下: 

1、生产者配置文件开启确认模式 

spring:
 rabbitmq:
   host: 192.168.0.162
   port: 5672
   username: itxiaotong
   password: itxiaotong
   virtual-host: /
    # 开启确认模式
   publisher-confirm-type: correlated

2、生产者定义确认模式的回调方法

@SpringBootTest
public class ProducerTest {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Test
    public void testConfirm(){
        // 定义确认模式的回调方法,消息向交换机发送后会调用confirm方法
      rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            /**
             * 被调用的回调方法
             * @param correlationData 相关配置信息
             * @param ack 交换机是否成功收到了消息
             * @param cause 失败原因
             */
            @Override
            public void confirm(CorrelationData correlationData,boolean ack, String cause) {
                if (ack){
                  System.out.println("confirm接受成功!");
               }else{
                  System.out.println("confirm接受失败,原因为:"+cause);
                    // 做一些处理。
               }
           }
       });
      rabbitTemplate.convertAndSend("my_topic_exchange","my_routing","send message...");
   }
}

实时效果反馈

1. 在RabbitMQ中,需要在中配置才能开启确认模式

A 生产者

B 消费者

C 生产者和消费者

D 不需要配置

2. 在RabbitMQ中,RabbitTemplate调用方法定义确认模式的回调方法

A setReturnsCallback

B setConfirmCallback

C setReturns

D setConfirm

消息的可靠性投递_退回模式 

RabbitMQ【消息的可靠性投递(概念、确认模式、退回模式、Ack)】(六)-全面详解(学习总结---从入门到深化)_System_03

退回模式(return)可以监听消息是否从交换机成功传递到队列, 使用方法如下:

1、生产者配置文件开启退回模式 

spring:
 rabbitmq:
   host: 192.168.0.162
   port: 5672
   username: itxiaotong
   password: itxiaotong
   virtual-host: /
    # 开启确认模式
   publisher-confirm-type: correlated
    # 开启回退模式
   publisher-returns: true

2、生产者定义退回模式的回调方法

@SpringBootTest
public class ProducerTest {
    @Autowired
     private RabbitTemplate rabbitTemplate;
    @Test
    public void testReturn(){
        // 定义退回模式的回调方法。交换机发送到队列失败后才会执行returnedMessage方法
       rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
            /**
             * @param returned 失败后将失败信息封装到参数中
             */
            @Override
            public void  returnedMessage(ReturnedMessage returned)
              {
                System.out.println("消息对象:"+returned.getMessage());
                System.out.println("错误码:"+returned.getReplyCode());
                System.out.println("错误信息:"+returned.getReplyText());
                System.out.println("交换机:"+returned.getExchange());
                System.out.println("路由键:"+returned.getRoutingKey());
                // 处理消息...
           }
       });
       rabbitTemplate.convertAndSend("my_topic_exchange","my_routing1","send message...");
   }
}

实时效果反馈

1. 在RabbitMQ中,退回模式可以监听

A 生产者是否成功传递到交换机

B 交换机是否成功传递到队列

C 消费者是否成功消费消息

D 以上都可以监听


2. 在RabbitMQ中,RabbitTemplate调用方法定义退回模式的回调方法

A setReturnsCallback

B setConfirmCallback

C setReturns

D setConfirm

消息的可靠性投递_Ack 

RabbitMQ【消息的可靠性投递(概念、确认模式、退回模式、Ack)】(六)-全面详解(学习总结---从入门到深化)_rabbitmq_04

在RabbitMQ中,消费者接收到消息后会向队列发送确认签收的消 息,只有确认签收的消息才会被移除队列。这种机制称为消费者消息确认(Consumer Acknowledge,简称Ack)。类似快递员派送 快递也需要我们签收,否则一直存在于快递公司的系统中。

消息分为自动确认和手动确认。自动确认指消息只要被消费者接收到,无论是否成功处理消息,则自动签收,并将消息从队列中移除。但是在实际开发中,收到消息后可能业务处理出现异常,那么 消息就会丢失。此时需要设置手动签收,即在业务处理成功再通知签收消息,如果出现异常,则拒签消息,让消息依然保留在队列当中。 

自动确认:spring.rabbitmq.listener.simple.acknowledge="none"

手动确认:spring.rabbitmq.listener.simple.acknowledge="manual" 

1、消费者配置开启手动签收 

spring:
 rabbitmq:
   host: 192.168.0.162
   port: 5672
   username: itxiaotong
   password: itxiaotong
   virtual-host: /
    # 开启手动签收
   listener:
     simple:
       acknowledge-mode: manual

2、消费者处理消息时定义手动签收和拒绝签收的情况

@Component
public class AckConsumer {
    @RabbitListener(queues = "my_queue")
    public void listenMessage(Message message, Channel channel) throws IOException, InterruptedException {
        // 消息投递序号,消息每次投递该值都会+1
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try {
             int i = 1/0; //模拟处理消息出现bug
             System.out.println("成功接受到消息:"+message);
             // 签收消息
             /**
              * 参数1:消息投递序号
              * 参数2:是否一次可以签收多条消息
              */
             channel.basicAck(deliveryTag,true);
          }catch (Exception e){
            System.out.println("消息消费失败!");
            Thread.sleep(2000);
            // 拒签消息
            /**
             * 参数1:消息投递序号
             * 参数2:是否一次可以拒签多条消息
             * 参数3:拒签后消息是否重回队列
             */
           channel.basicNack(deliveryTag,true,true);
       }
   }
}

实时效果反馈

1. 在RabbitMQ中,Ack可以监听

A 生产者是否成功传递到交换机

B 交换机是否成功传递到队列

C 消费者是否成功消费消息

D 以上都可以监听


2. 在RabbitMQ中,使用Ack手动签收一般在代码中的表现形式为

A 在 try 中签收消息

B 在 catch 中拒签消息

C 在 try 中签收消息,在 catch 中拒签消息

D 在 try 中拒签消息,在 catch 中签收消息

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: RabbitMQ

“RabbitMQ【消息的可靠性投递(概念、确认模式、退回模式、Ack)】(六)-全面详解(学习总结---从入门到深化)” 的相关文章