RabbitMQ高级(二) - MQ的可靠性

前一篇文章介绍了发送者的可靠性,保证的是消息可以成功的发送到 MQ,我们这篇文章主要介绍消息到了 MQ 之后,怎么保证消息不丢失。

在默认情况下,RabbitMQ 会将接收到的消息保存在内存中以降低消息收发的延迟。这样会导致两个问题:

  • 一旦 MQ 宕机,内存中的消息会丢失
  • 内存空间有限,当服务者故障或处理过慢时,会导致消息积压,引发 MQ 阻塞。

要解决上面所说的问题,可以通过以下的几个方法:

数据持久化

RabbitMQ 实现数据持久化包括三个方面:

  1. 交换机持久化

创建交换机的时候可以选择一个 Durability 属性:

  • Durable: 持久的,重启服务依然存在
  • Transient: 临时的,重启服务会消失

2. 队列持久化

和上面的交换机是一样的,只不过持久化的对象变成了队列

  1. 消息持久化

消息持久化,需要设置一个参数 delivery_mode = 2

SpringAMQP 发送的消息默认是持久化的

Lazy Queue

从 RabbitMQ 的 3.6.0 版本开始,就增加了 Lazy Queue 的概念,也就是惰性队列 惰性队列的特征如下:

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

在3.12版本后,所有的队列都是 Lazy Queue 模式,无法更改。

总结

RabbitMQ 如何保证消息的可靠性

  • 首先通过配置可以让交换机、队列、以及发送的消息都持久化。这样队列中的消息会持久化到磁盘,MQ 重启消息依然存在。
  • RabbitMQ 在 3.6 版本引入了 LazyQueue ,并且在 3.12 版本后成为队列的默认模式。LazyQueue 会将所有消息持久化。
  • 开启持久化和生产者确认时,RabbitMQ 只有在消息持久化完成后才会给生产者返回 ACK 回执。
相关推荐
就像楞次定律4 分钟前
【Linux 学习记之二】C++ 构建体系与底层链接机制的深度透视(1)
linux·后端
学到老活到老7 分钟前
第 22 集:Filter、Interceptor、AOP 都能拦截,为什么不能互换?
java·后端·spring
郭小李33 分钟前
spring 中的 @EnableWebMvc注解和WebMvcConfigurer接口
java·后端·spring
卷无止境40 分钟前
Skill 的安全边界在哪里:风险来源、验证思路与用户可用的防线
后端·python
星核0penstarry1 小时前
企业 API 向后兼容实战:版本控制、废弃字段通知与灰度发布策略
人工智能·后端·api·接口隔离原则·版本控制·架构设计·后端架构
用户别睡觉2 小时前
自己搭的中文 PDF RAG 接了 Redis 缓存、跑了 RAGAS,以为能写“提速多少、准确率多少”,结果两个都没按预期来。
后端
彭亚川Allen2 小时前
985 在职研究生到底怎么样?是不是水硕?是不是.....?
前端·后端·程序员
乘风2482 小时前
# 我做了个会遗忘的 AI 记忆,召回率反而从 8% 涨到 100%
后端
Rain的Java大神之路2 小时前
面试被LeetCode 27(移除元素)问懵?别再用两层 for 循环了:一道“简单题”吃透双指针原地删除,附面试加分话术 + 11 个避坑清单
后端·leetcode·面试
利威尔xu3 小时前
Go IM 源码实战(11):token 只是个 HASH,多端互踢的顺序错了就踢错人
后端·微服务·面试·架构·golang