带你从不同视角了解三大MQ

前言

首先我提一点我自己的学习心得,我通过最近学习项目,我觉得我们在学习新技术的时候,要始终记得有一个前提:技术的诞生是为了解决问题。

我们不要为了学而去学,这样其实没自己思考学的和理解的也比较慢,我在以前学习的时候就是因为别人项目用了所以我去学,这是不对的,我们应该带着问题去学,比如我之前学过rabbitmq,那我现在为什么会去学kafka和rocketmq,不是简单的因为大家都用我去学,而是如果未来遇到了大量数据,日志处理这种,需要巨大的吞吐量那rabbitmq就不行了,在比如我业务需要高可靠性,比如涉及到钱,那rocketmq的事务消息就可以排上用场了。

这是我在学习过程中叫ai写的一个静态网页。本文将基于这个网页的核心内容,带你从不同视角拆解三大 MQ

网站地址mqlearn

诞生背景

理解一款中间件,首先要回到它诞生的场景。三款 MQ 的起点完全不同,这直接决定了它们的设计哲学。

1. RabbitMQ ------ 金融基因,追求可靠与灵活路由

  • 2007 年诞生,源自金融领域的需求(银行、证券交易所)。

  • 率先实现 AMQP 0-9-1 协议,核心理念是"让中间件负责消息路由"。

  • 天然追求极高的可靠性灵活的消息分发,比如支持 direct、topic、fanout、headers 四种交换机,路由能力在三者中最强。

2. RocketMQ ------ 电商基因,追求高并发下的强一致与事务

  • 阿里巴巴自研,起源于双十一的超高并发交易场景。

  • 设计目标非常明确:在十万级 QPS 下,保证消息不丢、顺序不乱、事务一致

  • 自带事务消息(分布式事务终极方案之一)、同步刷盘、同步复制,是金融级可靠性的代名词。

3. Kafka ------ 大数据基因,追求极致吞吐与数据回溯

  • 2011 年 LinkedIn 开发,用于实时处理海量用户行为日志。

  • 设计哲学是把消息看作一条无界的"流",追求单机百万级吞吐、消息持久化和可任意回放。

  • 顺序写盘 + 零拷贝(sendfile)技术,使其成为大数据生态的事实标准。

核心特点差异

特点 RabbitMQ (仲裁队列) RocketMQ Kafka
持久化 消息声明 persistent,依赖 OS 刷盘 同步刷盘,立即写磁盘 依赖 Page Cache + 异步刷盘,靠副本保证可靠
吞吐量 万级 QPS 十万级 QPS 百万级 QPS
路由灵活度 四种交换机,极其灵活 通过 Topic + Tag 区分 主要通过 Topic 和 Key 哈希
消息顺序 单 Queue 内严格有序 单 MessageQueue 有序 单 Partition 有序
消息回溯 不支持 支持,但不如 Kafka 灵活 支持任意 offset 重置,天然可回放
高可用 仲裁队列 (Raft) Dledger (Raft) ISR + Leader 选举
事务消息 不支持 原生支持(两阶段) 不支持

可以看到,RocketMQ 和 RabbitMQ 更注重单条消息的可靠性和路由精细度,而 Kafka 则把"快"和"数据流"发挥到了极致。

架构设计

RabbitMQ 的架构

  • 单节点:Producer → Exchange → Queue(通过 Binding Key 绑定)→ Consumer

  • 集群 :镜像队列(已逐步废弃)或仲裁队列。仲裁队列基于 Raft 协议,写入需过半节点确认,自动选主,解决脑裂问题。

2. RocketMQ 的架构

  • 单节点:Producer → Broker(CommitLog 顺序写盘)→ MessageQueue → Consumer

  • 集群 :Master-Slave 同步复制 + Dledger(Raft 实现)自动选主。NameServer 作为去中心化路由中心,极轻量。

3. Kafka 的架构

  • 单节点:Producer → Broker(Partition 日志文件)→ Consumer

  • 集群 :每个 Partition 一主多从,通过 ISR(In-Sync Replicas) 动态管理同步副本,只从 ISR 中选新 Leader。元数据管理从 ZooKeeper 进化为 KRaft(Kafka 自己的 Raft 实现)。

常见消息队列问题

消息丢失:丢失消息我们要知道为什么丢从哪儿丢,其实无非就是生产者 ------》mq------ 》 消费者。无非就这条路上,所以三种mq的解决思路其实也都是在这条路上。

通用思路

  • 生产端:发送确认 + 失败重试

  • 存储端:多副本持久化 + 同步复制/多数派写入

  • 消费端:先处理业务,后提交/确认

MQ 独有机制
RabbitMQ(仲裁队列) • 基于 Raft 多数派写入,写入过半数节点才返回成功 • Publisher Confirm(发送方确认) • 消息和队列强制持久化
RocketMQ • 同步刷盘 + 同步复制(DLedger 模式) • DLedger 基于 Raft 自动故障转移,确保多数副本落盘 • 事务消息保证本地事务与发消息原子性
Kafka acks=all + min.insync.replicas ≥ 2 • 只从 ISR 中选举新 Leader,落后副本不能当选 • 可开启幂等生产者(避免网络重试导致重复,但主要防重复)

重复消费

其实这个也就是幂等性问题,在业务中我所知道的就一下几种。

1.通过redis+token:简单来说就是用户进入页面,前端发请求,然后后端给token并存redis,用户真正点击提交,前端携带数据和token,后端直接删除token,如果成功说明没有,如果失败说明有。

2.数据库唯一索引:这种方式我们一般来说都是作为兜底,比如优惠券业务,数据库对优惠券id和用户id建立唯一索引,那么同一用户购买两张一样的就会失败,数据库只会插入一条数据。

3.还可以用redis的setnx命令,通过set key value nx ex ms 像这个key的话可以用uuid,如果设置成功那就可以,设置失败那就不行,过期时间的话1小时或者更久或者几分钟。这里有一个极端问题万一key一样咋办,我通过ai了解到可以用hashkey,这样redis的value就是hashkey,不再是只要key设置失败就行,而是value也一样才行。

消息堆积

通用思路

  • 增加消费者实例(水平扩展)

  • 消费端限流(控制拉取频率/prefetch)

  • 设置消息保留时间,过期自动清理或转移死信队列

各 MQ 独特方案

MQ 独有实现
RabbitMQ 惰性队列 (Lazy Queue):消息直接存磁盘,堆积亿级不占内存 • 仲裁队列本身数据在磁盘,天然抗堆积 • basic.qos 控制 prefetch,精细限制消费者处理速率
RocketMQ • CommitLog 顺序写,堆积不影响性能 • 消费进度管理,消息可回溯 • 队列数决定并行度,需提前规划,扩容不易
Kafka • 分区数限制最大并行度,堆积时需增加分区(影响顺序) • 日志保留策略(按时间/大小)自动清理 • 新版本分级存储(Tiered Storage),冷数据入廉价对象存储,避免磁盘爆满

总结

更详细的内容可以在静态网页里面看,不要去背,去理解,然后时不时打开这篇文章看看或者打开网页看看。网站地址mqlearn

唉在这个所有人卷到飞起世界,我甚至不知道这条路到底对不对,不过我有一个想法就是,反正人吧就这么活一次而已,我总得有一个我自己擅长的领域吧,就当爱好了,哪怕以后吃不上这碗饭也无妨了,我还是会持续开发和我的codex创造出一个伟大的,让后续的计算机学生一看见就直呼卧槽的项目和设计。就当意淫了。

相关推荐
冰心孤城13 小时前
C++ 与 C#混合编程 示例 (基于VS)
java·c++·c#
~光~~13 小时前
【xv6学习】L0_环境配置
单片机·嵌入式硬件·学习
阿里云云原生14 小时前
RocketMQ-A2A 创新论文入选 ACM FSE,定义 AI Agent 可靠协作新范式
apache·rocketmq
实验如有神祝女士15 小时前
不同参数规模大模型在医学翻译场景的适配差异
论文阅读·人工智能·深度学习·学习·算法·语言模型·论文笔记
风中芦苇啊15 小时前
Java EasyExcel 导入通用工具类:自定义注解映射字段 + 反射机制
java·开发语言
家有娇妻张兔兔15 小时前
Java 对接 PLC 主流型号最合适的方案:Apache PLC4X 实战指南
java·开发语言·plc·modbus·数据缓存·西门子s7·apache plc4x
晚安code16 小时前
RabbitMQ消息可靠性:发送确认、消费者ACK与SpringAMQP实战
rabbitmq
独行侠影a16 小时前
Rust vs. Zig:2026年系统编程语言的“双雄争霸”,谁更适合替代C++?
java·开发语言
摇滚侠16 小时前
Codebuddy 官网 Codebuddy IntelliJ IDEA 插件 阅读笔记 2
java·笔记·intellij-idea