RabbitMQ如何保证生产者发送消息可靠?

1.生产者可靠

首先要配置RabbitMQ的生产者的失败重连机制,如此就可以避免由于网络波动导致的消息发送失败问题

如果是由于其他原因导致的失败,RabbitMQ还支持生产者确认机制,当发生消息到MQ时会返回一个ACK的回执,如果发送失败会返回一个NACK的回执

以上手段都会导致性能下降

2.MQ可靠

数据持久化:MQ重启后仍然存在,不会丢失

交换机持久化(默认持久化)

队列持久化(默认持久化)

消息持久化:将Delivery mode 设置为 2 - Persistent

Spring中RabbitTemplate发送消息默认是持久化

LazyQueue:惰性队列

  • 接收到消息后直接存入磁盘而非内存(内存中只保留最近的消息,当前版本默认2048条)
  • 消费者要消费消息时才会从磁盘中读取并加载到内存
  • 支持数百万条的消息存储

3.12版本之后,所以的队列都是LazyQueue,无法更改

3.消费者可靠性

消费者确认机制

为了确认消费者是否成功处理消息,RabbitMQ提供了消费者确认机制。当消费者处理消息结束后,应该向RabbitMQ发送一个回执,告知RabbitMQ自己消息处理状态。回执有三种可选值:

  • ack:成功处理消息,RabbitMQ从队列中删除该消息
  • nack:消息处理失败,RabbitMQ需要再次投递消息
  • reject:消息处理失败并拒绝该消息,RabbitMQ从队列中删除该消息

SpringAMQP已经实现了消息确认功能。并允许我们通过配置文件选择ACK处理方式:

  • none:不处理。消息投递给消费者后立刻ACK,消息立刻从MQ中删除。非常不安全
  • manual:手动处理,手动在业务代码中调用api,返回ack或reject,存在业务入侵,但更灵活
  • auto:自动模式,利用AOP对消息处理逻辑进行环绕通知,当业务正常执行时返回ack,否则如果业务异常自动返回nack,如果消息处理或校验异常自动返回reject

spring.rabbitmq.listener.simple.acknowledge-mode=auto/none/manual

失败重试机制

当消费者出现异常后,消息会不断地重新入队到队列,再重新发送给消费者,然后再次异常,再次重新入队,无限循环,导致mq消息处理飙升,造成不必要的压力

使用Spring的retry机制

失败消息处理策略:

在开启重试模式后,重试次数耗尽,如果消息依然失败,则需要有MessageRecoverer接口来处理,它包含三种不同的实现:

  • RejectAndDontRequeueRecoverer:重试耗尽后,直接reject,丢弃消息。默认就是这种方式
  • ImmediateRequeueMessageRecoverer:重试耗尽后,返回nack,消息重新入队
  • RepublishMessageRecoverer:重试耗尽后,将失败消息投递到指定的交换机

将失败处理策略改为RepublishMessageRecoverer:

1.首先,定义接受失败消息的交换机,队列及其绑定关系;

2.然后,定义RepublishMessageRecoverer


 

<think>好的,我现在需要帮助用户了解RabbitMQ确保消息可靠投递的机制。首先,我需要回顾一下自己之前学过的相关知识,确保回答准确。 用户的问题是关于RabbitMQ可靠消息投递保证机制和确认模式。根据用户提供的三个引用内容,我需要整合这些信息,并按照系统级指令的要求来组织回答。首先,引用[1]提到RabbitMQ在设计时就考虑了可靠性投递,并提供了多种机制。这是总起,可以放在开头部分。 接下来,引用[2]详细说明了生产者确认机制的两个环节:Broker接收消息的确认和服务端确认机制,包括事务模式和确认模式。引用[3]补充了配置相关的参数,比如publisher-confirm-type和publisher-returns,以及手动确认模式。需要将这些内容分点说明,确保结构清晰。 系统级指令要求使用中文回答,生成相关问题,正确使用LaTeX格式,并且引用标识要自然添加。我需要检查是否有数学公式,但当前主题可能不涉及太多数学内容,但如果有变量或代码示例,需注意格式。例如,配置参数可能需要用代码块展示。 然后,需要生成相关问题,考虑用户可能进一步想了解的内容,比如如何配置确认模式、事务与确认模式的区别、消息持久化的具体步骤等。需要确保问题相关且有价值。 在组织回答时,按照用户可见层的指示,结构要清晰,分步骤说明机制,引用标识放在相关段落的末尾。例如,在提到生产者确认机制时,引用[2]和[3]的信息,并在段落末尾添加[^2][^3]。 最后,检查LaTeX语法是否正确,虽然当前内容可能用不到复杂公式,但如果有代码块或配置示例,要正确使用格式。例如,配置文件中的参数可能需要用行内代码或代码块展示,如`publisher-confirm-type: CORRELATED`。 总结步骤: 1. 开头概述RabbitMQ可靠投递机制。 2. 分点详细说明生产者确认机制、消息持久化、消费者手动确认。 3. 每个点下再细分小点,如确认模式的两种方式,持久化的配置,手动确认的必要性。 4. 添加配置示例,引用对应的引用来源。 5. 生成相关问题,覆盖配置、机制对比、持久化、高可用等方面。 需要确保每个引用正确对应到内容,例如事务模式和确认模式的区别来自引用[2],配置参数来自引用[3],可靠性投递的整体机制来自引用[1]。 可能需要注意的地方:用户提供的引用[3]中的配置是Spring的yml配置,需要说明这是在Spring框架中的设置,而RabbitMQ本身也有相关参数,可能需要区分开来。但根据引用内容,直接使用提供的配置示例即可,并正确标注引用来源。 现在开始组织内容,确保每个部分自然衔接,引用标识正确,结构清晰,符合用户的要求。</think>### RabbitMQ可靠消息投递机制详解 RabbitMQ通过以下核心机制确保消息可靠投递,涵盖生产者到交换机、队列再到消费者的全链路: --- #### 一、生产者确认机制(Publisher Confirms) 1. **服务端确认模式(Confirm Mode)** - 生产者发送消息后,RabbitMQ服务端会返回确认应答(ACK)或失败应答(NACK)。 - **普通确认模式**:异步监听`ConfirmCallback`,适用于批量确认。 - **关联确认模式**:通过`CorrelationData`绑定消息与应答,支持逐条确认[^3]。 - 配置示例(Spring): ```yaml spring: rabbitmq: publisher-confirm-type: CORRELATED publisher-returns: true ``` 2. **事务模式(Transaction Mode)** - 通过`channel.txSelect()`开启事务,消息提交后才会被投递,但性能较低,通常推荐使用确认模式替代。 --- #### 二、消息持久化(Message Durability) 1. **交换机与队列持久化** - 声明时设置`durable=true`,防止服务重启后元数据丢失: ```java channel.exchangeDeclare("exchange", BuiltinExchangeType.DIRECT, true); channel.queueDeclare("queue", true, false, false, null); ``` 2. **消息持久化标记** - 发送消息时设置`MessageProperties.PERSISTENT_TEXT_PLAIN`,确保消息体持久化到磁盘[^1]。 --- #### 三、消费者手动确认(Manual Acknowledgement) 1. **关闭自动应答** 配置消费者手动确认模式,避免消息未处理完成就被标记为已消费: ```yaml spring: rabbitmq: listener: simple: acknowledge-mode: manual ``` 2. **显式发送ACK/NACK** - 处理成功后调用`channel.basicAck()`确认消息。 - 处理失败时调用`channel.basicNack()`拒绝消息,可选择重新入队或进入死信队列。 --- #### 四、失败补偿机制 1. **ReturnCallback处理未路由消息** 当消息无法路由到队列时,通过`ReturnCallback`记录日志或重试。 2. **死信队列(DLX)** 将超时或多次重试失败的消息转发到死信队列,实现异常隔离。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值