消息确认共分为两个方面,一个是生产者推送消息确认,一个是消费者接收消息的确认。
此篇文章讲解的是 生产者推送消息确认。
生产者推送消息确认
表示由生产者端发送消息到中间件服务端后,回调其发送结果。用于处理中间件无法正常接收消息的情况,如消息无法路由到对应队列、无法发送到对应交换器等。
首先,先分析生产者推送消息的可能出现情况:
- 消息推送到server,但找不到对应Exchange;
- 消息推送到server,找到Exchange,但没找到匹配的Queue;
- 消息推送到server,找不到Exchange也找不到Queue;
- 消息推送到server,成功推送到Queue;
对于上面的四种情况,RabbitMQ提供了两个回调函数,分别是 ConfirmCallback 和 ReturnsCallback。
回调函数配置:
@Configuration
public class RabbitMQConfig {
/**
* 初始化 rabbitTemplate
* @param connectionFactory
* @return
*/
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
/**
* 消息序列化
*/
rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
/**
* 发送消息确认
*/
// ConfirmCallback
// 消息发送到Exchange的回调函数,需要在application.yml添加 publisher-confirm-type: correlated 来开启
rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
System.out.println("【ConfirmCallback】相关数据:" + correlationData);
System.out.println("【ConfirmCallback】确认情况:" + ack);
System.out.println("【ConfirmCallback】原因:" + cause);
});
// ReturnsCallback
// 需要这里开启Mandatory,确保消息在未被队列接收时回调,若只在application.yml添加 publisher-returns: true 测试无效
rabbitTemplate.setMandatory(true);
rabbitTemplate.setReturnsCallback(returnedMessage -> {
System.out.println("【ReturnsCallback】消息:" + returnedMessage.getMessage());
System.out.println("【ReturnsCallback】回应码:" + returnedMessage.getReplyCode());
System.out.println("【ReturnsCallback】回应信息:" + returnedMessage.getReplyText());
System.out.println("【ReturnsCallback】交换器:" + returnedMessage.getExchange());
System.out.println("【ReturnsCallback】路由键:" + returnedMessage.getRoutingKey());
});
return rabbitTemplate;
}
}
application.yml:
spring:
application:
name: rabbitmq-producer
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
virtual-host: /debug
publisher-confirm-type: correlated #确认消息已发送到 Exchange,默认是none
示例一:
示例二:
示例结果说明:
- ConfirmCallback无论消息是否成功发送到Exchange都会返回回调结果。
- ReturnsCallback则(前提是消息成功发送到Exchange)只有在Exchange无法将消息成功转发到Queue时才会返回回调信息。