RabbitMQ:发送者的可靠性之使用消息确认回调

在开发消息驱动的系统时,消息的可靠传递至关重要。而RabbitMQ作为一个广泛使用的消息队列中间件,提供了多种消息确认机制,确保消息从生产者到交换器,再到队列的传递都能被监控和确认。今天,我想分享一下如何在Spring中配置和使用RabbitMQ的消息确认回调功能,并讨论一些实际使用中的注意事项。

配置RabbitMQ的ConfirmCallback

首先,我们需要在application.ymlapplication.properties中配置RabbitTemplate,使其支持消息确认回调:

spring:
  rabbitmq:
    publisher-confirm-type: correlated # 开启publisher confirm机制,并设置confirm类型
    publisher-returns: true # 开启publisher return机制

这些配置项用于开启RabbitMQ的消息确认(publisher confirm)和消息返回(publisher return)机制。接下来,我们需要在Spring的配置类中进行相应的配置:

package com.itheima.publisher.config;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

@Slf4j
@Configuration
@RequiredArgsConstructor
public class MqConfig {
    private final RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init() {
        rabbitTemplate.setReturnsCallback(returned -> {
            log.error("触发return callback,");
            log.debug("exchange: {}", returned.getExchange());
            log.debug("routingKey: {}", returned.getRoutingKey());
            log.debug("message: {}", returned.getMessage());
            log.debug("replyCode: {}", returned.getReplyCode());
            log.debug("replyText: {}", returned.getReplyText());
        });
    }
}

在这个配置类中,我们通过@PostConstruct注解的方法初始化了RabbitTemplate的ReturnsCallback。这一回调方法会在消息无法路由到队列时被触发,记录详细的错误信息。

使用ConfirmCallback发送消息

接下来,我们来看如何在发送消息时使用ConfirmCallback来确认消息是否成功发送到交换器:

@Test
public void testConfirmCallback() throws InterruptedException {
    // 0.创建correlationData
    CorrelationData cd = new CorrelationData(UUID.randomUUID().toString());
    cd.getFuture().addCallback(new ListenableFutureCallback<CorrelationData.Confirm>() {
        @Override
        public void onFailure(Throwable ex) {
            log.error("spring amqp 处理确认结果异常", ex);
        }

        @Override
        public void onSuccess(CorrelationData.Confirm result) {
            // 判断是否成功
            if (result.isAck()) {
                log.debug("收到ConfirmCallback ack,消息发送成功");
            } else {
                log.error("收到ConfirmCallback nack,消息发送失败!reason:{}", result.getReason());
            }
        }
    });
    
    // 1.交换名
    String exchangeName = "hmall.direct";
    // 2.消息
    String message = "hello everyone";
    rabbitTemplate.convertAndSend(exchangeName, "blue222", message, cd);
    Thread.sleep(2000); // 或更长时间
}

在这个测试方法中,我们首先创建了一个CorrelationData对象,并为其添加了回调方法。这个回调方法在消息发送成功或失败时会被触发,从而记录相关日志信息。然后,我们指定交换器名称和消息内容,使用RabbitTemplate的convertAndSend方法发送消息并附带CorrelationData对象。

实际使用中的注意事项

虽然开启生产者确认机制能够有效保证消息传递的可靠性,但这种机制会消耗更多的MQ性能。因此,在实际使用中,需要慎重考虑是否开启生产者确认机制。下面是几种会触发确认的情况:

  1. 路由失败:一般是因为RoutingKey错误导致,往往是编程错误引起的。
  2. 交换机名称错误:同样是编程错误导致。
  3. MQ内部故障:这种情况需要处理,但发生概率较低。

因此,只有在对消息可靠性要求非常高的业务场景中才需要开启生产者确认机制,并且只需要开启ConfirmCallback处理nack即可。对于一般的业务场景,建议通过完善的编码规范和严格的测试来避免上述编程错误,从而减少不必要的性能开销。

总结

通过以上配置和代码,我们可以实现对RabbitMQ消息的确认回调,从而提高消息传递的可靠性。在实际开发中,这种机制可以帮助我们更好地监控和管理消息传递过程中的各种问题,确保消息的准确投递。然而,需要根据具体业务需求权衡性能和可靠性之间的关系。

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RabbitMQ 中,可以通过设置消息确认机制来保证消息可靠性消息确认机制主要包括两个方面:生产者消息确认和消费者消息确认。 生产者消息确认是指生产者发送消息到 Broker 后,通过消息确认机制获取消息是否成功发送到 Broker 的确认信息。在实际开发中,可以通过设置 ConfirmCallback 回调函数来处理生产者消息确认的结果。 下面是一个示例代码: ```java import com.rabbitmq.client.Channel; import com.rabbitmq.client.ConfirmCallback; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import java.io.IOException; import java.util.concurrent.TimeoutException; public class Producer { private static final String QUEUE_NAME = "my_queue"; private static Connection connection; private static Channel channel; public static void main(String[] args) throws IOException, TimeoutException { // 连接 RabbitMQ ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); connection = factory.newConnection(); channel = connection.createChannel(); // 声明队列 channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 开启消息确认模式 channel.confirmSelect(); // 设置消息确认回调 channel.addConfirmListener(new ConfirmCallback() { @Override public void handle(long deliveryTag, boolean multiple) throws IOException { if (multiple) { System.out.println("Messages have been confirmed up to " + deliveryTag); } else { System.out.println("Message has been confirmed: " + deliveryTag); } } }); // 发送消息 String message = "Hello, RabbitMQ!"; channel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8")); System.out.println("Sent message: " + message); // 关闭连接 channel.close(); connection.close(); } } ``` 在上述代码中,我们使用了 channel.confirmSelect() 方法开启消息确认模式,并通过 channel.addConfirmListener() 方法设置了消息确认回调函数 ConfirmCallback。当消息确认发送到 Broker 后,ConfirmCallback 回调函数会被调用,可以处理消息发送结果。在回调函数中,deliveryTag 表示消息的唯一标识,multiple 表示是否是批量确认。 希望这个回答能够帮到您!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值