如何保证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确认信息就会删除消息

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

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

需要根据业务需求

相关推荐
麦兜*13 小时前
深入解析现代分布式事务架构:基于Seata Saga模式与TCC模式实现金融级高可用与数据最终一致性的工程实践全解析
分布式·金融·架构
難釋懷14 小时前
分布式锁-redission功能介绍
分布式
only-qi16 小时前
微服务场景下,如何实现分布式事务来保证一致性?
分布式·微服务·架构
m0_5648768418 小时前
Distributed data parallel (DDP)分布式训练
分布式
BYSJMG19 小时前
计算机毕设选题推荐:基于Hadoop的交通事故数据可视化分析系统
大数据·vue.js·hadoop·分布式·后端·信息可视化·课程设计
野犬寒鸦19 小时前
从零起步学习并发编程 || 第三章:JMM(Java内存模型)详解及对比剖析
java·服务器·开发语言·分布式·后端·学习·spring
虫小宝21 小时前
查券返利机器人的异步任务调度:Java XXL-Job+Redis实现海量查券请求的分布式任务分发
java·redis·分布式
yq1982043011561 天前
构建高可用资源导航平台:基于Django+Scrapy的分布式架构实践
分布式·scrapy·django
你这个代码我看不懂1 天前
Kafka常见问题解答
分布式·kafka
Tony Bai1 天前
Git 即数据库:Beads (bd) —— 专为 AI Agent 打造的分布式任务追踪引擎
数据库·人工智能·分布式·git