RabbitMQ消息的可靠投递


RabbitMQ提供了两种方式来解决消息投递的可靠性,避免消息丢失或消息投递失败的情况

  • confirm确认模式
  • return退回模式

SpringBoot中需要开启响应配置才能使用,如果不设置消息投递失败后,默认丢弃消息,不会进行任何回调。

spring:
  rabbitmq:
    publisher-confirm-type: correlated
    publisher-returns: true
rabbitTemplate.setMandatory(true);

mandatory:用于设置处理失败消息的方式,直接丢失还是返回给消息生产者
(1)当mandatory标志位设置为true时,如果exchange根据自身类型和消息routingKey无法找到一个合适的queue存储消息,那么broker会调用basic.return方法将消息返还给生产者
(2)当mandatory设置为false时,出现上述情况broker会直接将消息丢弃,回调方法也不会执行
RabbitMQ整个消息投递的过程:
producer→RabbitMQ broker→exchange→queue→consumer 【其中消息实际是存放在queue中】

  • 消息从producer投递到exchange,会返回一个confirmCallback。无论是否投递成功,都会返回。当ack=true,表示成功,当ack=fase,表示失败
  • 消息从exchange投递到queue,投递失败则会返回一个returnCallback

ConfirmCallback

设置confirm确认模式分为两步:
(1)配置中开启confirm确认模式
(2)在RabbitTemplate中定义ConfirmCallback的实现类【建议通过lambda表达式实现】

@FunctionalInterface
public interface ConfirmCallback {
	/**
	 * @param correlationData 相关配置信息
	 * @param ack true代表ack【确认,接收成功】, false代表nack【未确认,接收失败】
	 * @param cause 失败原因
	 */
	void confirm(@Nullable CorrelationData correlationData, boolean ack, @Nullable String cause);
}

实际应用:RabbitTemplate必须设置为多例,才能如下使用

@Test
public void test() {
    User user = new User();
    user.setId(1);
    user.setUsername("老大");
    rabbitTemplate.setConfirmCallback((data, ack, cause) -> {
        if (!ack) {
            log.error("消息发送失败!" + cause + data.toString());
        } else {
            log.info("消息发送成功,消息ID:" + (data != null ? data.getId() : null));
        }
    });
    rabbitTemplate.convertAndSend(RabbitConMQConfig.PURCHASE_DIRECT_EXCHANGE, RabbitConMQConfig.PURCHASE_ORDER_ROUTING_KEY, user,
    new CorrelationData(String.valueOf(user.getId())))
}

CorrelationData对象,用于设置发送消息时需要投递的额外配置新,CorrelationData 对象内部只有一个 id 属性,用来表示当前消息唯一性。实际开发中CorrelationData id是与业务无关的,发送的id需要记录下来用于纠错和对账

ReturnCallback

设置return回退模式分为三步:
(1)配置中开启return回退模式:spring.rabbitmq.publisher-returns=true
(2)设置Exchange处理消息的模式:spring.rabbitmq.template.mandatory=true

  1. 消息没有路由到Queue,则丢弃消息【默认配置】
  2. 消息没有路由到Queue,则返回消息给消息生产者producer

(3)在RabbitTemplate中定义ReturnCallback的实现类【建议通过lambda表达式实现】,回调中可以接收到第(2)步中返回的消息,并进行处理
如果设置了spring.rabbitmq.publisher-returns=true,但未设置spring.rabbitmq.template.mandatory=true,则Exchange没有找到Queue就会丢弃掉消息, 而不会触发回调

@FunctionalInterface
public interface ReturnCallback {
	/**
	 * @param 投递失败后Exchange返回给消息生产者的消息
	 * @param 返回的错误码
	 * @param 返回的错误信息
	 * @param 交换机名称
	 * @param 路由键
	 */
	void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey);
}
@Test
public void test() {
    User user = new User();
    user.setId(1);
    user.setUsername("老大");
    rabbitTemplate.setConfirmCallback((data, ack, cause) -> {
        if (!ack) {
            log.error("消息发送失败!" + cause + data.toString());
        } else {
            log.info("消息发送成功,消息ID:" + (data != null ? data.getId() : null));
        }
    });

    rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
        log.info("消息丢失:exchange({}),route({}),replyCode({}),replyText({}),message:{}", exchange, routingKey, replyCode, replyText, message);
    });
    rabbitTemplate.convertAndSend(RabbitConMQConfig.PURCHASE_DIRECT_EXCHANGE, RabbitConMQConfig.PURCHASE_ORDER_ROUTING_KEY, user, new CorrelationData(String.valueOf(user.getId())));
}

消息的可靠投递小结

确认模式:

  1. 设置ConnectionFactory的publisher-confirm-type=correlated,开启confirm确认模式
  2. 使用rabbitTemplate.setConfirmCallback设置回调函数,当消息发送到Exchange后回调confirm方法,在方法中判断ack,如果为true,则发送成功。如果为false,则发送失败

回退模式:

  1. 设置ConnectionFactory的publisher-returns=true,开启confirm确认模式
  2. 使用rabbitTemplate.setReturnCallback设置spring.rabbitmq.publisher-returns=true,当消息由Exchange路由到queue失败后,如果设置了 spring.rabbitmq.template.mandatory=true,则消息回回退给消息生产者producer,并执行回调函数

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RabbitMQ 是一个开源的消息队列,它采用了 AMQP 协议来实现消息可靠传输。AMQP 协议提供了消息确认机制,保证消息在发送到队列之后得到确认,以避免消息的丢失。 RabbitMQ 实现消息可靠投递主要有以下几个方面: 1. 消息确认机制:RabbitMQ 支持消息的确认机制,当消息被成功接收并处理后,消费者可以给 RabbitMQ 发送一个确认消息,告诉 RabbitMQ 这个消息已经被成功处理了。如果 RabbitMQ 没有收到消费者的确认消息,那么它会将消息重新发送给另一个消费者进行处理。 2. 持久化机制:RabbitMQ 支持将消息持久化到磁盘上,以防止消息RabbitMQ 重启时丢失。如果消息需要被持久化,生产者需要将消息的 delivery mode 设置为 2。 3. 生产者确认机制:RabbitMQ 支持生产者确认机制,当生产者发送消息RabbitMQ 后,可以等待 RabbitMQ 发送确认消息给生产者,告诉生产者消息已经被成功接收并保存。如果 RabbitMQ 无法接收消息,则会返回一个 Nack 消息给生产者,告诉它消息发送失败。 4. 重试机制:RabbitMQ 支持消息的重试机制,如果消息没有被成功处理,RabbitMQ 会将消息重新发送给另一个消费者进行处理,直到消息被成功处理为止。 综上所述,RabbitMQ 提供了多种机制来保证消息可靠投递,可以根据实际情况选择合适的机制来保证消息可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值