上海古都建筑设计集团,上海办公室装修设计公司,上海装修公司高质量的内容分享社区,上海装修公司我们不是内容生产者,我们只是上海办公室装修设计公司内容的搬运工平台

rabbitMQ发送消息,回调方法,查看是否进入交换机以及队列

guduadmin251月前

http://t.csdn.cn/3xMJk      使用rabbitmq发送邮件。

接着上文使用rabbitmq发送邮件,本篇文章就讲讲,当发送消息失败,我们该怎么确认是那个环节出错了,是在发送邮件时没有到达交换机、还是没有到达队列呢?

rabbitmq提供了回调接口,当发送消息失败的时候,无法准确到达交换机,或者无法被正确路由到目标队列时触发回调方法。

首先需要创建一个类去实现两个接口 ConfirmCallback、ReturnCallback

1、对于confirm方法是用来判断消息是否到达交换机,参数ack是布尔值。true到达交换机。false没有到达交换机。

2、对于returnedMessage方法使用来判断是否到达队列,只要回调这个方法,那就是没有到达队列。没有回调有两种情况:一种消息都没有到达交换机,一种消息到达交换机,没有到达队列

/**
 * @author weixinxin 2023-07-13
 **/
@Slf4j
@Component
public class RabbitMQAckConfig implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnCallback {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @PostConstruct
    public void init(){
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
    }
    //判断是否到达交换机
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (ack){
            log.info("消息到了交换机");
            System.out.println("消息到了交换机 -------------");
        }else {
            log.info("消息没有到达交换机");
            System.out.println("消息没有到交换机----------------- ");
        }
    }
    //判断是否到达队列
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        System.out.println("message消息 = " + new String(message.getBody()));
        System.out.println("replyCode应答码 = " + replyCode);
        System.out.println("replyText描述 = " + replyText);
        System.out.println("exchange交换机 = " + exchange);
        System.out.println("routingKey路由key = " + routingKey);
    }
}

光有上面代码还不行,你还需要开启rabbitmq发布确认机制,和返回机制 

因为rabbitmq这两个机制默认一个none:不启用,一个false:不启用消息返回

其实在我上篇rabbitmq发送邮件的application-dev.properties中已经配置过了

spring.rabbitmq.publisher-confirm-type=correlated
spring.rabbitmq.publisher-returns=true

完整的配置:

#RabbitMQ
spring.rabbitmq.port=5672
spring.rabbitmq.host=localhost
spring.rabbitmq.username=admin
spring.rabbitmq.password=admin
spring.rabbitmq.publisher-confirm-type=correlated
spring.rabbitmq.publisher-returns=true
spring.rabbitmq.virtual-host=TestHost

这里还有一个配置讲一下:

spring.rabbitmq.virtual-host=TestHost

这是配置 RabbitMQ 的虚拟主机 (Virtual Host) 的属性。可以为 RabbitMQ 连接配置指定要使用的虚拟主机。如果不设置该属性,默认使用的是 RabbitMQ 服务器上的默认虚拟主机 "/”。

他的作用:

实现对不同应用程序或环境的隔离,从而更好地管理和控制消息队列的使用。每个虚拟主机都拥有自己的独立资源,如队列、交换机和绑定等,可以在不同的虚拟主机中创建相互独立的消息队列和交换机。

rabbitMQ发送消息,回调方法,查看是否进入交换机以及队列,第1张

rabbitMQ发送消息,回调方法,查看是否进入交换机以及队列,第2张

/**
 * @author weixinxin 2023-07-14
 **/
public class RabbitMqConst {
    public static final String EXCHANGE_TEST = "exchange.test";
    public static final String ROUTING_TEST = "routing.test";
    public static final String QUEUE_TEST  = "queue.test";
}

测试一下:

/**
 * @author weixinxin 2023-07-14
 **/
@RestController
@RequestMapping("/rabbitMq")
public class RabbitMqController {
    @Autowired
    private RabbitMqService rabbitMqService;
    @GetMapping("/sent")
    public String sendConfirm(){
        //交换机+1,肯定到达不了 
rabbitMqService.sentMassage(RabbitMqConst.EXCHANGE_TEST+"1",RabbitMqConst.ROUTING_TEST,"大胆小儿,还不速速退下");
        return "消息发送成功";
    }
}

发送消息:

/**
 * @author weixinxin 2023-07-14
 **/
@Service
public class RabbitMqService {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    public Boolean sentMassage(String exchange, String routingKey, String massage){
        rabbitTemplate.convertAndSend(exchange,routingKey,massage);
        return true;
    }
}

监听器:

/**
 * @author weixinxin 2023-07-14
 **/
@Component
public class ConfirmReceiver {
    @SneakyThrows
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = RabbitMqConst.QUEUE_TEST, durable = "true", autoDelete = "false"),
            exchange = @Exchange(value = RabbitMqConst.EXCHANGE_TEST),
            key = (RabbitMqConst.ROUTING_TEST)
    ))
    public void confirmTest(String msg, Message message, Channel channel) {
        System.out.println("msg = " + msg);
        System.out.println("message = " + new String(message.getBody()));
        //手动确认
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }

rabbitMQ发送消息,回调方法,查看是否进入交换机以及队列,第3张

 下面测试消息没有到达队列:

/**
 * @author weixinxin 2023-07-14
 **/
@RestController
@RequestMapping("/rabbitMq")
public class RabbitMqController {
    @Autowired
    private RabbitMqService rabbitMqService;
    @GetMapping("/sent")
    public String sendConfirm(){
        //routingkey+1        
rabbitMqService.sentMassage(RabbitMqConst.EXCHANGE_TEST,RabbitMqConst.ROUTING_TEST+"1","大胆小儿,还不速速退下");
        return "消息发送成功";
    }
}

rabbitMQ发送消息,回调方法,查看是否进入交换机以及队列,第4张

 很明显routingkey不对

如果 交换机 和 路由key 都不对,也只会回调到是否到达交换机:

    @GetMapping("/sent")
    public String sendConfirm(){
        rabbitMqService.sentMassage(RabbitMqConst.EXCHANGE_TEST+"1",RabbitMqConst.ROUTING_TEST+"1","大胆小儿,还不速速退下");
        return "消息发送成功";
    }

 rabbitMQ发送消息,回调方法,查看是否进入交换机以及队列,第5张

网友评论

搜索
最新文章
热门文章
热门标签
 
 梦见被鬼追赶  原版周公解梦口诀  梦见鬼魂是什么预兆