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 服务器上的默认虚拟主机 "/”。
他的作用:
实现对不同应用程序或环境的隔离,从而更好地管理和控制消息队列的使用。每个虚拟主机都拥有自己的独立资源,如队列、交换机和绑定等,可以在不同的虚拟主机中创建相互独立的消息队列和交换机。
/** * @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); }
下面测试消息没有到达队列:
/** * @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 "消息发送成功"; } }很明显routingkey不对
如果 交换机 和 路由key 都不对,也只会回调到是否到达交换机:
@GetMapping("/sent") public String sendConfirm(){ rabbitMqService.sentMassage(RabbitMqConst.EXCHANGE_TEST+"1",RabbitMqConst.ROUTING_TEST+"1","大胆小儿,还不速速退下"); return "消息发送成功"; }
猜你喜欢
网友评论
- 搜索
- 最新文章
- 热门文章