RabbitMQ学习笔记:mandatory、publisher-confirms、publisher-return属性区别

rabbitmq客户端发送消息首先发送的交换器exchange,然后通过路由键routingKey和bindingKey比较判定需要将消息发送到那个队列queue上;在这个过程有两个地方消息可能丢失,第一消息发送到交换器exchange的过程,第二消息从交换器exchange发送到队列queue的过程;

1.publiser-confirm模式可以确保生产者到交换器exchange消息有没有发送成功
#设置此属性配置可以确保消息成功发送到交换器
spring.rabbitmq.publisher-confirms=true
2.publisher-return模式可以在消息没有被路由到指定的queue时将消息返回,而不是丢弃
#可以确保消息在未被队列接收时返回
spring.rabbitmq.publisher-returns=true

在使用上面的属性配置时通常会和mandatory属性配合一起使用:

#指定消息在没有被队列接收时是否强行退回还是直接丢弃
spring.rabbitmq.template.mandatory=true

到这里你可能会有一个疑问,这两个配置都是指定未找到合适队列时将消息退回,究竟是如何分别起作用呢?接下来我们看下RabbitAutoConfiguration自动化配置类就清楚了:

        @Bean
        @ConditionalOnSingleCandidate(ConnectionFactory.class)
        @ConditionalOnMissingBean
        public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
            PropertyMapper map = PropertyMapper.get();
            RabbitTemplate template = new RabbitTemplate(connectionFactory);
            MessageConverter messageConverter = (MessageConverter)this.messageConverter.getIfUnique();
            if (messageConverter != null) {
                template.setMessageConverter(messageConverter);
            }
						//设置rabbitmq处理未被queue接收消息的模式
            template.setMandatory(this.determineMandatoryFlag());
            Template properties = this.properties.getTemplate();
            if (properties.getRetry().isEnabled()) {
                template.setRetryTemplate((new RetryTemplateFactory((List)this.retryTemplateCustomizers.orderedStream().collect(Collectors.toList()))).createRetryTemplate(properties.getRetry(), Target.SENDER));
            }

            properties.getClass();
            map.from(properties::getReceiveTimeout).whenNonNull().as(Duration::toMillis).to(template::setReceiveTimeout);
            properties.getClass();
            map.from(properties::getReplyTimeout).whenNonNull().as(Duration::toMillis).to(template::setReplyTimeout);
            properties.getClass();
            map.from(properties::getExchange).to(template::setExchange);
            properties.getClass();
            map.from(properties::getRoutingKey).to(template::setRoutingKey);
            properties.getClass();
            map.from(properties::getDefaultReceiveQueue).whenNonNull().to(template::setDefaultReceiveQueue);
            return template;
        }
				//判定是否将未找到合适queue的消息退回
        private boolean determineMandatoryFlag() {
          	/**
              * 获取spring.rabbitmq.template.mandatory属性配置;
              * 这里面会有三种可能,为null、false、true
              * 而只有在mandatory为null时才会读取publisher-return属性值
              **/
            Boolean mandatory = this.properties.getTemplate().getMandatory();
            return mandatory != null ? mandatory : this.properties.isPublisherReturns();
        }

阅读上面的源码可以获取如下信息:

  1. spring.rabbitmq.template.mandatory属性的优先级高于spring.rabbitmq.publisher-returns的优先级
  2. spring.rabbitmq.template.mandatory属性可能会返回三种值null、false、true,
  3. spring.rabbitmq.template.mandatory结果为true、false时会忽略掉spring.rabbitmq.publisher-returns属性的值
  4. spring.rabbitmq.template.mandatory结果为null(即不配置)时结果由spring.rabbitmq.publisher-returns确定

GitHub地址:https://github.com/mingyang66/spring-parent

### 关于 `spring.rabbitmq.publisher-confirms` 的弃用及其替代方案 在 Spring Boot 配置中,某些属性可能会随着版本迭代而被标记为废弃(Deprecated)。对于 `spring.rabbitmq.publisher-confirms` 属性而言,其功能是为了启用 RabbitMQ 发布确认机制。然而,在较新的 Spring Boot 版本中,该属性已被移除或替换。 #### 替代方案 为了实现相同的功能,可以通过自定义配置来设置发布确认模式。具体方法是在应用程序启动时通过编程方式显式配置 RabbitMQ 的连接工厂(ConnectionFactory),从而开启发布确认支持。以下是实现此目标的一个示例: ```java import org.springframework.amqp.core.MessagePostProcessor; import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RabbitMqConfig { @Bean public ConnectionFactory connectionFactory() { CachingConnectionFactory connectionFactory = new CachingConnectionFactory(); connectionFactory.setHost("localhost"); connectionFactory.setPort(5672); connectionFactory.setUsername("guest"); connectionFactory.setPassword("guest"); // 启用发布确认 connectionFactory.setPublisherConfirms(true); return connectionFactory; } } ``` 上述代码片段展示了如何手动配置 RabbitMQ 的连接工厂以启用发布确认[^4]。这种方式不仅提供了更大的灵活性,还能够更好地适配不同场景下的需求。 #### 原因分析 Spring Boot 对部分配置项进行调整的主要原因是简化框架内部逻辑并减少冗余配置的可能性。例如,直接通过 Java 代码控制连接行为相比依赖外部化配置文件更加直观且易于维护。此外,这种变化也反映了 Spring Boot 不断优化用户体验的努力方向[^5]。 如果需要进一步了解有关 RabbitMQ 的运维扩展以及最佳实践,则可参考相关内容说明[^1];而对于 Spring Boot 核心配置方面的问题,则建议查阅官方文档或其他权威资料获取最新指导信息[^2]。 ---
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值