RabbitMQ(八) 回退消息

329 阅读2分钟

在仅开启了生产者确认机制的情况下,交换机接收到消息后,会直接给消息生产者发送确认消息,如果发现该消息不可路由,那么消息会被直接丢弃,此时生产者是不知道消息被丢弃这个事件的。那么如何让无法被路由的消息帮我想办法处理一下?最起码通知我一声,我好自己处理啊。通过设置mandatory参数可以在当消息传递过程中不可达目的地时将消息返回给生产者。

  1. 配置文件
spring.rabbitmq.publisher-returns=true
  1. 回退接口
 @Component
 @Slf4j
 public class MyCallBack implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnsCallback {

 @Autowired
 private RabbitTemplate rabbitTemplate;

 @PostConstruct
 public void init(){
     //注入
     rabbitTemplate.setConfirmCallback(this);
     rabbitTemplate.setReturnsCallback(this);
 }

 /*
 * 交换机确认回调方法,发消息后,交换机接收到了就回调
 *   1.1 correlationData:保存回调消息的ID及相关信息
 *   1.2 b:交换机收到消息,为true
 *   1.3 s:失败原因,成功为null
 *
 * 发消息,交换机接受失败,也回调
 *   2.1 correlationData:保存回调消息的ID及相关信息
 *   2.2 b:交换机没收到消息,为false
 *   2.3 s:失败的原因
 *
  * */

 @Override
 public void confirm(CorrelationData correlationData, boolean b, String s) {
     String id = correlationData!=null ? correlationData.getId():"";
     if (b){
         log.info("交换机已经收到ID为:{}的信息",id);
     }else {
         log.info("交换机还未收到ID为:{}的消息,由于原因:{}",id,s);
     }
 }

 //可以在当消息传递过程中不可达目的的时将消息返回给生产者
 //只有不可达目的地的时候才可回退
 @Override
 public void returnedMessage(ReturnedMessage returnedMessage) {
     log.error("消息{},被交换机{}退回,退回的原因:{},路由Key:{}",
             new String(returnedMessage.getMessage().getBody())
             , returnedMessage.getExchange()
             , returnedMessage.getReplyText()
             , returnedMessage.getRoutingKey());
   }
 }

  1. 发布测试
 // 开始发消息 测试确认
 @RestController
 @Slf4j
 @RequestMapping("/confirm")
 public class ProducerController {

 @Autowired
 private RabbitTemplate rabbitTemplate;

 //发消息
 @GetMapping("/sendMessage/{message}")
 public void sendMessage(@PathVariable String message){
     CorrelationData correlationData = new CorrelationData("1");
     rabbitTemplate.convertAndSend(ConfirmConfig.CONFIRM_EXCHANGE_NAME
             ,ConfirmConfig.CONFIRM_routing_key
             ,message+"key1",correlationData);
     log.info("发送消息内容:{}",message+"key1");

     CorrelationData correlationData2 = new CorrelationData("2");
     rabbitTemplate.convertAndSend(ConfirmConfig.CONFIRM_EXCHANGE_NAME
             ,ConfirmConfig.CONFIRM_routing_key+"2"
             ,message+"key12",correlationData2);
     log.info("发送消息内容:{}",message+"key12");
 }
}

4.效果:实现回退消息成功!

image.png