RabbitMQ消息可靠性投递

RabbitMQ消息投递的路径为:
生产者 —> 交换机 —> 队列 —> 消费者
在RabbitMQ工作的过程中,每个环节消息都可能传递失败,那么RabbitMQ是如何监听消息是否成功投递的呢?
确认模式(confirm)可以监听消息是否从生产者成功传递到交换机。
退回模式(return)可以监听消息是否从交换机成功传递到队列。
消费者消息确认(Consumer Ack)可以监听消费者是否成功处理消息。

开启确认模式

publisher-confirm-type: correlated

@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...");
   }
}


消息回退

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

@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...");
   }
}

消息确认
自动确认:spring.rabbitmq.listener.simple.acknowledge=“none”
手动确认:spring.rabbitmq.listener.simple.acknowledge=“manual”
消费者处理消息时定义手动签收和拒绝签收的情况

@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);
     }
   }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值