RabbitMQ-生产端confirm确认机制和return机制

本文深入探讨了消息队列中生产端的确认机制,包括Confirm确认机制和Return消息机制。详细介绍了如何在生产者投递消息后,通过Broker的应答确保消息可靠投递,以及如何处理不可路由消息,提供了具体的代码示例。

一. 什么是生产端 confirm确认机制

消息确认的理解:是指生产者投递消息后, 如果Broker收到消息, 则会给我们产生一个应答,生产者进行接收应答, 用来确定这条消息是否正常发送到Broker, 这种方式也是消息的可靠性投递的核心保障

二. 在生产端实现confirm确认机制

  1. 在channel上开启确认模式 : channel.confirmSelect()
  2. 在channel上添加监听 : addConfirmListener, 监听成功和失败的返回结果, 根据具体的结果对消息进行重新发送, 或记录日志等后续处理
  //添加一个确认监听
  channel.addConfirmListener(new ConfirmListener() {
  	@Override //失败
  	public void handleNack(long deliveryTag, boolean multiple) throws IOException {
  		System.err.println("-------no ack!-----------");
  	}
  	
  	@Override //成功
  	public void handleAck(long deliveryTag, boolean multiple) throws IOException {
  		System.err.println("-------ack!-----------");
  	}
  });

三.生产端return消息机制

  1. Return Listener用于处理一些不可路由的消息
  2. 正常情况下消息生产者通过指定一个Exchange和RoutingKey, 把消息送到某一个队列中去, 然后消费者监听队列, 进行消费操作
  3. 但在某些情况下, 如果在发送消息的时候, 当前的exchange不存在或者指定的路由key路由不到, 这个时候如果我们需要监听这种不可达的消息, 就要使用Return Listener
  4. 在基础API中有一个关键的配置项Mandatory : 如果为true, 则监听器会接收到路由不可达的消息, 然后进行后续处理, 如果为false, 那么broker端自动删除该消息
//添加的return消息机制
channel.addReturnListener((replyCode, replyText, exchange1, routingKey1, properties, body) -> {
            System.out.println("——handle return——");
            System.out.println("replyCode:" + replyCode);
            System.out.println("replyText:" + replyText);
            System.out.println("exchange1:" + exchange1);
            System.out.println("routingKey1:" + routingKey1);
            System.out.println("properties:" + properties);
            System.out.println("body:" + new String(body));
        });
<think>我们正在使用Spring MVC整合RabbitMQ,并配置生产确认机制(Publisher Confirms)。用户询问在XML配置中如何设置`publisher-confirm-type`。 根据引用[2]中的YAML配置示例,我们看到在YAML中配置了: ```yaml spring: rabbitmq: publisher-confirm-type: correlated ``` 但是,用户使用的是XML配置,并且是Spring MVC项目(非Spring Boot)。在传统的Spring XML配置中,我们需要通过`RabbitConnectionFactoryBean`或直接在连接工厂上设置相关属性来实现。 在Spring AMQP中,生产确认机制(也称为发布者确认)是通过在连接工厂上设置`publisherConfirms`属性来启用的。在XML配置中,我们通常配置一个`ConnectionFactory` bean,然后设置其属性。 然而,需要注意的是,`publisher-confirm-type`是Spring Boot引入的配置项,用于更精细地控制确认类型(如`correlated`)。在非Spring Boot的Spring XML配置中,我们通常直接设置连接工厂的`publisherConfirms``publisherReturns`属性为`true`,然后通过`RabbitTemplate`的配置来支持关联的确认(correlated confirms)。 具体步骤: 1. 配置连接工厂,开启生产确认返回模式。 2. 配置RabbitTemplate,设置`confirm-callback``return-callback`(用于关联确认)。 在XML中,我们可以这样配置: ```xml <!-- 配置连接工厂 --> <rabbit:connection-factory id="connectionFactory" host="127.0.0.1" port="5672" username="guest" password="guest" publisher-confirms="true" <!-- 开启生产确认 --> publisher-returns="true"/> <!-- 开启返回模式(当消息无法路由到队列时返回给生产者) --> <!-- 配置RabbitTemplate --> <rabbit:template id="rabbitTemplate" connection-factory="connectionFactory" confirm-callback="confirmCallback" <!-- 确认回调的Bean引用 --> return-callback="returnCallback" <!-- 返回回调的Bean引用 --> mandatory="true"/> <!-- 设置为true,当消息不可路由时才会触发return-callback --> ``` 这里,`publisher-confirms="true"`相当于Spring Boot中的`publisher-confirm-type=simple`或`correlated`的开启,但在非Boot环境中,我们通过设置这个属性为`true`来开启确认,并且通过`confirm-callback``return-callback`来实现关联确认。 注意:在非Boot的Spring XML配置中,没有直接名为`publisher-confirm-type`的属性,而是通过`publisher-confirms``publisher-returns`两个独立的属性来开启,然后通过回调接口实现关联。 回调接口的实现: 我们需要定义两个Bean,一个实现`RabbitTemplate.ConfirmCallback`接口,另一个实现`RabbitTemplate.ReturnCallback`接口。 例如: ```java public class RabbitConfirmCallback implements RabbitTemplate.ConfirmCallback { @Override public void confirm(CorrelationData correlationData, boolean ack, String cause) { // 处理确认结果 } } public class RabbitReturnCallback implements RabbitTemplate.ReturnCallback { @Override public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) { // 处理返回的消息 } } ``` 然后在XML中声明这些Bean并注入到RabbitTemplate中: ```xml <bean id="confirmCallback" class="com.example.RabbitConfirmCallback"/> <bean id="returnCallback" class="com.example.RabbitReturnCallback"/> ``` 这样,当消息发送到Broker后,会异步调用这些回调方法。 总结: 在Spring MVC的XML配置中,没有直接名为`publisher-confirm-type`的配置项,而是通过: - 在连接工厂上设置`publisher-confirms="true"`来开启生产确认- 在连接工厂上设置`publisher-returns="true"`来开启消息返回。 - 在RabbitTemplate上设置`confirm-callback``return-callback`属性来指定回调Bean,以实现关联确认。 因此,用户需要按照上述方式配置即可实现生产确认机制。 相关问题: 1. 在Spring MVC中如何实现RabbitMQ生产确认的同步等待? 2. RabbitMQ生产确认机制中,`CorrelationData`的作用是什么? 3. 如何确保在消息发送失败时进行重试? 4. RabbitTemplate的`mandatory`属性有什么作用?</think>### Spring MVC 配置 RabbitMQ 生产确认机制(XML 配置) 在 Spring MVC 中使用 XML 配置 RabbitMQ生产确认机制,需要配置两个关键属性:`publisher-confirms` `publisher-returns`。以下是完整配置步骤: #### 1. 配置连接工厂(启用确认机制) ```xml <rabbit:connection-factory id="connectionFactory" host="127.0.0.1" port="5672" username="guest" password="guest" publisher-confirms="true" <!-- 开启生产确认 --> publisher-returns="true"/> <!-- 开启消息回退机制 --> ``` - `publisher-confirms="true"`:启用 Broker 确认机制(类似 `publisher-confirm-type` 功能) - `publisher-returns="true"`:启用消息无法路由时的回退机制 #### 2. 配置 RabbitTemplate(设置回调) ```xml <rabbit:template id="rabbitTemplate" connection-factory="connectionFactory" confirm-callback="confirmCallback" <!-- 确认回调Bean --> return-callback="returnCallback" <!-- 回退回调Bean --> mandatory="true"/> <!-- 强制消息路由检查 --> ``` #### 3. 实现回调接口(Java 代码) ```java public class RabbitConfirmCallback implements RabbitTemplate.ConfirmCallback { @Override public void confirm(CorrelationData correlationData, boolean ack, String cause) { if(ack) { System.out.println("消息到达Broker: " + correlationData.getId()); } else { System.out.println("消息丢失: " + cause); } } } public class RabbitReturnCallback implements RabbitTemplate.ReturnCallback { @Override public void returnedMessage( Message message, int replyCode, String replyText, String exchange, String routingKey ) { System.out.println("消息无法路由: " + new String(message.getBody())); } } ``` #### 4. 注册回调 Bean(XML 配置) ```xml <bean id="confirmCallback" class="com.example.RabbitConfirmCallback"/> <bean id="returnCallback" class="com.example.RabbitReturnCallback"/> ``` #### 5. 完整配置示例 ```xml <!-- RabbitMQ 连接 --> <rabbit:connection-factory id="connectionFactory" host="127.0.0.1" publisher-confirms="true" publisher-returns="true"/> <!-- 模板配置 --> <rabbit:template id="rabbitTemplate" connection-factory="connectionFactory" confirm-callback="confirmCallback" return-callback="returnCallback" mandatory="true"/> <!-- 回调实现 --> <bean id="confirmCallback" class="com.example.RabbitConfirmCallback"/> <bean id="returnCallback" class="com.example.RabbitReturnCallback"/> <!-- 队列声明 --> <rabbit:queue name="order.queue"/> <rabbit:direct-exchange name="order.exchange"> <rabbit:bindings> <rabbit:binding queue="order.queue" key="order.routing"/> </rabbit:bindings> </rabbit:direct-exchange> ``` ### 关键配置说明: 1. **publisher-confirms** 控制是否启用生产确认(相当于 Spring Boot 中的 `publisher-confirm-type`),设置为 `true` 启用 2. **confirm-callback** 指定实现 `RabbitTemplate.ConfirmCallback` 接口的 Bean,处理以下情况: - `ack=true`:消息成功到达 Broker - `ack=false`:消息丢失(Broker 不可用或队列不存在) 3. **return-callback** 指定实现 `RabbitTemplate.ReturnCallback` 接口的 Bean,处理消息无法路由到队列的情况 4. **mandatory="true"** 强制检查消息路由,当消息无法路由时触发 return-callback(必须设置为 true) > **性能提示**:生产环境建议使用异步确认机制,同步确认会阻塞发送线程[^2] ### 工作流程: ```mermaid sequenceDiagram Producer->>Broker: 发送消息 Broker-->>Producer: 确认接收(ack/nack) alt 消息无法路由 Broker->>Producer: 触发returnCallback end ``` ### 测试验证 ```java // 发送消息时携带关联ID rabbitTemplate.convertAndSend("order.exchange", "order.routing", message, new CorrelationData(UUID.randomUUID().toString())); ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值