注意:
- 在需要使用消息的return机制时候,
mandatory
参数必须设置为true
- 新版本开启消息的confirm配置publisher-confirms已经过时,改为使用
publisher-confirm-type
参数设置(correlated:开启;NONE:关闭)
1.配置文件和核心依赖
spring:
rabbitmq:
username: guest
password: guest
virtual-host: /
addresses: 192.168.3.8:5672
#开启消息的return机制
publisher-returns: true
#在需要使用消息的return机制时候,此参数必须设置为true
template:
mandatory: true
#开启消息的confirm机制
publisher-confirm-type: correlated
<!--springboot版本2.3.7.RELEASE-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
- 声明队列和交换机并绑定
package com.vivo.demo2.springamqp;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author:luzaichun
* @Date:2021/1/1
* @Time:23:02
**/
@Configuration
public class RabbtimqConfig {
@Bean("topicQueue")
public Queue queue() {
return new Queue("topic.queue", false, false, false);
}
@Bean("topicExchange")
public Exchange exchange() {
return new TopicExchange("topic.exchange", false, false);
}
@Bean
public Binding topicQueueBindingTopicExchange(Queue topicQueue,Exchange topicExchange) {
return BindingBuilder.bind(topicQueue).to(topicExchange).with("topic.#").noargs();
}
}
- 封装一个用于发送消息的类
package com.vivo.demo2.springamqp;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import java.util.UUID;
/**
* @author:luzaichun
* @Date:2021/1/2
* @Time:19:47
**/
@Component
public class MQSender {
@Autowired
private RabbitTemplate rabbitTemplate;
//配置confirm监听具体处理,确认消息到达MQ,根据实际业务场景处理
final RabbitTemplate.ConfirmCallback confirmCallback = new RabbitTemplate.ConfirmCallback(){
@Override
public void confirm(@Nullable CorrelationData correlationData, boolean ack, @Nullable String cause) {
System.out.println("=============confirmCallBack触发。消息到达MQ broker===========");
System.out.println("correlationDataID="+correlationData.getId());
System.out.println("ack="+ack);
System.out.println("cause="+cause);
if (!ack){
System.err.println("异常处理。。。。");
}
}
};
//配置return监听处理,消息无法路由到queue,根据实际业务操作
final RabbitTemplate.ReturnCallback returnCallback = new RabbitTemplate.ReturnCallback() {
@Override
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
System.out.println("=============returnCallback触发。消息路由到queue失败===========");
System.out.println("msg="+new String(message.getBody()));
System.out.println("replyCode="+replyCode);
System.out.println("replyText="+replyText);
System.out.println("exchange="+exchange);
System.out.println("routingKey="+routingKey);
}
};
public void sendMessage(String exchange,String routingKey,String message){
//设置消息的confirm监听,监听消息是否到达exchange
rabbitTemplate.setConfirmCallback(confirmCallback);
//设置消息的return监听,当消息无法路由到queue时候,会触发这个监听。
rabbitTemplate.setReturnCallback(returnCallback);
//correlationDataId相当于消息的唯一表示
UUID correlationDataId = UUID.randomUUID();
CorrelationData correlationData = new CorrelationData(correlationDataId.toString());
rabbitTemplate.convertAndSend(exchange,routingKey,message,correlationData);
}
}
- 测试使用
package com.vivo.demo2;
import com.vivo.demo2.springamqp.MQSender;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @author:luzaichun
* @Date:2021/1/1
* @Time:23:22
**/
@SpringBootTest
public class Test1 {
@Autowired
private MQSender mqSender;
@Test
public void test1(){
//测试confrim
mqSender.sendMessage("topic.exchange","topic.aaaa","测试消息到达MQ broker触发confirm机制");
//测试return
mqSender.sendMessage("topic.exchange","aaaa","测试消息无法路由到queue触发returnCallBack");
}
}
最后观察结果发现,两条消息都能触发confirm,因为都能正确到达MQ Broker;第二条消息因为无法路由到queue所以触发了returnCallBack