如何保证RabbitMQ的可靠性传输

文章目录

producer到broke

发送方确认

生产者到交换机:confirm

可能因为网络的原因

交换机到队列:returns模式

代码或者配置层错误,导致路由是失败

(快递地址写错了)

队列也是有一些特性:长度,有效期

队列溢出:可以采用死信等方式

消息对列自身数据丢失(持久化)

方法名 方法功能 所属接口 接口所属类
confirm() 确认消息是否发送到交换机 ConfirmCallback RabbitTemplate
returnedMessage() 确认消息是否发送到队列 ReturnsCallback RabbitTemplate

①ConfirmCallback接口

这是RabbitTemplate内部的一个接口,源代码如下:

java 复制代码
	/**
	 * A callback for publisher confirmations.
	 *
	 */
	@FunctionalInterface
	public interface ConfirmCallback {

		/**
		 * Confirmation callback.
		 * @param correlationData correlation data for the callback.
		 * @param ack true for ack, false for nack
		 * @param cause An optional cause, for nack, when available, otherwise null.
		 */
		void confirm(@Nullable CorrelationData correlationData, boolean ack, @Nullable String cause);

	}

生产者端发送消息之后,回调confirm()方法

  • ack参数值为true:表示消息成功发送到了交换机
  • ack参数值为false:表示消息没有发送到交换机

②ReturnCallback接口

同样也RabbitTemplate内部的一个接口,源代码如下:

java 复制代码
	/**
	 * A callback for returned messages.
	 *
	 * @since 2.3
	 */
	@FunctionalInterface
	public interface ReturnsCallback {

		/**
		 * Returned message callback.
		 * @param returned the returned message and metadata.
		 */
		void returnedMessage(ReturnedMessage returned);

	}

注意:接口中的returnedMessage()方法仅在消息没有发送到队列时调用

ReturnedMessage类中主要属性含义如下:

属性名 类型 含义
message org.springframework.amqp.core.Message 消息以及消息相关数据
replyCode int 应答码,类似于HTTP响应状态码
replyText String 应答码说明
exchange String 交换机名称
routingKey String 路由键名称
java 复制代码
package com.atguigu.mq.config;

import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class MQProducerAckConfig implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnsCallback{

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init() {
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnsCallback(this);
    }

    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (ack) {
            log.info("消息发送到交换机成功!数据:" + correlationData);
        } else {
            log.info("消息发送到交换机失败!数据:" + correlationData + " 原因:" + cause);
        }
    }

    @Override
    public void returnedMessage(ReturnedMessage returned) {
        log.info("消息主体: " + new String(returned.getMessage().getBody()));
        log.info("应答码: " + returned.getReplyCode());
        log.info("描述:" + returned.getReplyText());
        log.info("消息使用的交换器 exchange : " + returned.getExchange());
        log.info("消息使用的路由键 routing : " + returned.getRoutingKey());
    }
}

Broke内部

持久化

交换机,队列,消息

在后台管理界面创建交换机和队列时,默认就是持久化的模式。
此时消息也是持久化的,不需要额外设置。

创建备份交换机

备份交换机一定要选择fanout类型,因为原交换机转入备份交换机时并不会指定路由键

Broke到达消费者

消费者异常,消息还没到消费者,比如说消费者宕机,消费逻辑有问题

手动确认

默认情况下,消费端取回消息后,默认会自动返回ACK确认消息,所以在前面的测试中消息被消费端消费之后,RabbitMQ得到ACK确认信息就会删除消息

但实际开发中,消费端根据消息队列投递的消息执行对应的业务,未必都能执行成功,如果希望能够多次重试,那么默认设定就不满足要求了

(但是可靠性不是越高越好,可靠性高性能有可能降低!)

需要根据业务需求

相关推荐
zquwei4 小时前
SpringCloudGateway+Nacos注册与转发Netty+WebSocket
java·网络·分布式·后端·websocket·网络协议·spring
道一云黑板报8 小时前
Flink集群批作业实践:七析BI批作业执行
大数据·分布式·数据分析·flink·kubernetes
飞来又飞去9 小时前
kafka sasl和acl之间的关系
分布式·kafka
MZWeiei10 小时前
Zookeeper的监听机制
分布式·zookeeper
莹雨潇潇10 小时前
Hadoop完全分布式环境部署
大数据·hadoop·分布式
浩哲Zhe11 小时前
RabbitMQ
java·分布式·rabbitmq
明达技术12 小时前
分布式 IO 模块:赋能造纸业,革新高速纸机主传动
分布式
Allen Bright12 小时前
RabbitMQ中的Topic模式
分布式·rabbitmq
李洋-蛟龙腾飞公司14 小时前
HarmonyOS Next 应用元服务开发-分布式数据对象迁移数据权限与基础数据
分布式·华为·harmonyos
rainoway14 小时前
CRDT宝典 - Multi-Value-Register
前端·分布式·算法