RocketMQ、Kafka 和 RabbitMQ 等中间件对比

这篇文章资料来自于网络,是对部分知识整理,这里只是记录一下,仅供参考

一、架构设计:谁的底层更能打?

RocketMQ 的 "轻量级" 架构

RocketMQ 采用 "NameServer+Broker+Producer+Consumer" 的经典架构,最大特点是无状态设计

  • NameServer:作为路由注册中心,轻量且无状态,支持集群部署但节点间不通信,通过 Producer/Consumer 定期心跳更新路由信息
  • Broker:负责消息存储和转发,采用主从架构实现高可用,支持同步 / 异步复制
  • Topic 路由:通过队列分片实现负载均衡,每个 Topic 默认分为 4 个队列,可动态扩展

核心优势在于部署简单,无需依赖第三方组件(如 ZooKeeper),单节点即可启动,集群扩展成本低。

Kafka 的 "重量级" 集群

Kafka 架构依赖 ZooKeeper 实现分布式协调:

  • 所有元数据(主题、分区、消费组)都存储在 ZooKeeper 中
  • Broker 节点分为 Controller 和 Follower,Controller 负责分区 Leader 选举
  • 消息按分区存储,通过多副本机制保证可靠性

这种架构的问题在于组件耦合度高,ZooKeeper 集群的稳定性直接影响 Kafka 可用性,且大规模集群下 ZooKeeper 容易成为性能瓶颈。

RabbitMQ 的 "交换机" 模型

RabbitMQ 基于 AMQP 协议设计,架构核心是交换机(Exchange)

  • 支持 Direct、Topic、Fanout 等多种交换类型,路由规则灵活
  • 消息存储在内存中,持久化需显式配置
  • 采用 Erlang 语言开发,集群部署依赖 Cookie 认证

优势是路由灵活,但 Erlang 语言的特性导致二次开发成本高,且大规模消息堆积时性能下降明显。

二、优缺点、性能实测

Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点

特性 ActiveMQ RabbitMQ RocketMQ Kafka
单机吞吐量 万级,比 RocketMQ、Kafka 低一个数量级 同 ActiveMQ 10 万级,支撑高吞吐 10 万级,高吞吐,一般配合大数据类的系统来进行实时数据计算、日志采集等场景
topic 数量对吞吐量的影响 topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降,这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 topic topic 从几十到几百个时候,吞吐量会大幅度下降,在同等机器下,Kafka 尽量保证 topic 数量不要过多,如果要支撑大规模的 topic,需要增加更多的机器资源
时效性 ms 级 微秒级,这是 RabbitMQ 的一大特点,延迟最低 ms 级 延迟在 ms 级以内
可用性 高,基于主从架构实现高可用 同 ActiveMQ 非常高,分布式架构 非常高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用
消息可靠性 有较低的概率丢失数据 基本不丢 经过参数优化配置,可以做到 0 丢失 同 RocketMQ
功能支持 MQ 领域的功能极其完备 基于 erlang 开发,并发能力很强,性能极好,延时很低 MQ 功能较为完善,还是分布式的,扩展性好 功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用

吞吐量对比(基于相同硬件)

在 16 核 32G 服务器上的测试数据:

消息队列 单节点 TPS(1KB 消息) 集群 TPS(3 节点)
RocketMQ 5 万 + 15 万 +
Kafka 4 万 + 12 万 +
RabbitMQ 1.5 万 + 4 万 +

RocketMQ 的吞吐量优势在大规模集群 中更明显,这得益于其零拷贝技术批量消息处理机制:

  • 采用 MMAP+PageCache 实现消息文件的高效读写
  • 支持批量发送 / 拉取消息,减少网络 IO 次数
  • 消息存储按 CommitLog 文件顺序写入,避免磁盘随机 IO

延迟表现

小消息(100B)场景下的 P99 延迟:

  • RocketMQ:~10ms
  • Kafka:~15ms
  • RabbitMQ:~20ms

RocketMQ 的延迟控制更优,因为其消息投递采用长轮询机制,Consumer 可设置合理的等待时间(默认 30s),减少空轮询带来的开销。

三、功能特性:谁的生态更完善?

事务消息:金融级可靠性

RocketMQ 的分布式事务消息是其杀手锏功能:

复制代码
// 1. 发送半事务消息
TransactionMQProducer producer = new TransactionMQProducer("tx_producer_group");
producer.setTransactionListener(new TransactionListener() {
    @Override
    public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        // 执行本地事务
        return LocalTransactionState.UNKNOW;
    }
    
    @Override
    public LocalTransactionState checkLocalTransaction(MessageExt msg) {
        // 事务回查
        return LocalTransactionState.COMMIT_MESSAGE;
    }
});
// 2. 发送消息
SendResult result = producer.sendMessageInTransaction(msg, null);

通过 "半消息 + 事务回查" 机制,实现分布式事务的最终一致性,这是 Kafka(需自行实现)和 RabbitMQ(插件支持不完善)无法比拟的。

消息重试与死信队列

  • RocketMQ:支持消费失败自动重试,可设置重试次数(默认 16 次)和重试间隔,失败消息自动进入死信队列
  • Kafka:无内置重试机制,需业务代码实现,消费位移提交机制复杂
  • RabbitMQ:支持重试但默认无限重试,需手动配置死信交换机

RocketMQ 的重试策略更贴合业务实际,避免消息无限重试导致的资源浪费。

定时消息

RocketMQ 支持任意精度的定时消息 (如 3 秒后投递),而 Kafka 需通过延迟队列模拟(精度低),RabbitMQ 仅支持固定级别的延迟(如 10ms、10s)。实现方式上,RocketMQ 通过定时任务 + 时间轮机制,在 Broker 端完成消息的延迟投递,不占用 Consumer 资源。

四、适用场景:谁是你的最佳选择?

优先选 RocketMQ 的场景

  1. 金融级业务:需要事务消息、高可靠性的支付、订单系统
  1. 大规模集群:如电商平台的双 11 峰值流量(百万级 TPS 需求)
  1. 复杂业务路由:需要 - tag 过滤、定时消息等高级特性
  1. 国产化需求:对开源协议(Apache v2)和社区响应速度有要求

考虑 Kafka 的场景

  1. 日志采集:ELK 生态的标配,适合海量日志的异步传输
  1. 大数据场景:与 Spark、Flink 等计算框架集成更成熟
  1. 流式处理:需要基于消息的实时计算能力

选择 RabbitMQ 的场景

  1. 中小规模应用:如内部系统的通知、告警功能
  1. 复杂路由需求:需要灵活的交换机路由规则
  1. 快速原型开发:部署简单,开箱即用

五、踩坑经验:从实战中总结的教训

  1. RocketMQ 的 NameServer 高可用

单节点 NameServer 存在单点风险,生产环境需部署 3 + 节点,Producer/Consumer 配置多个 NameServer 地址(用分号分隔)

  1. Kafka 的分区数量陷阱

分区数并非越多越好,每个分区都会占用内存和文件句柄,建议单个 Broker 的分区总数不超过 2000

  1. RabbitMQ 的内存控制

默认配置下,内存使用达到 40% 会阻塞生产者,需通过vm_memory_high_watermark参数调整阈值

六、RocketMQ 和 Kafka 到底有什么区别?

(1) 适用场景

Kafka适合日志处理;

RocketMQ适合业务处理。

结论:平手,根据具体业务定夺。

(2) 性能

Kafka单机写入 TPS 号称在百万条/秒;

RocketMQ 大约在10万条/秒。

结论:追求性能的话,Kafka单机性能更高。

(3) 可靠性

RocketMQ支持异步/同步刷盘;异步/同步Replication;

Kafka使用异步刷盘方式,异步Replication。

结论:RocketMQ所支持的同步方式提升了数据的可靠性。

(4) 实时性

均支持pull长轮询,RocketMQ消息实时性更好

结论:RocketMQ 胜出。

(5) 支持的队列数

Kafka单机超过64个队列/分区,消息发送性能降低严重;

RocketMQ 单机支持最高5万个队列,性能稳定

结论:长远来看,RocketMQ 胜出,这也是适合业务处理的原因之一

(6) 消息顺序性

Kafka 某些配置下,支持消息顺序,但是一台Broker宕机后,就会产生消息乱序;

RocketMQ支持严格的消息顺序,在顺序消息场景下,一台Broker宕机后,

发送消息会失败,但是不会乱序;

结论:RocketMQ 胜出

(7)消费失败重试机制

Kafka消费失败不支持重试

RocketMQ消费失败支持定时重试,每次重试间隔时间顺延。

(8)定时/延时消息

Kafka不支持定时消息;

RocketMQ支持定时消息

(9)分布式事务消息

Kafka不支持分布式事务消息;

阿里云ONS支持分布式定时消息,未来开源版本的RocketMQ也有计划支持分布式事务消息

(10)消息查询机制

Kafka不支持消息查询

RocketMQ支持根据Message Id查询消息,也支持根据消息内容查询消息

(11)消息回溯

Kafka理论上可以按照Offset来回溯消息

RocketMQ支持按照时间来回溯消息,精度毫秒,例如从一天之前的某时某分某秒开始重新消费消息

为什么阿里会自研RocketMQ?

(1)Kafka的业务应用场景主要定位于日志传输;对于复杂业务支持不够

(2)阿里很多业务场景对数据可靠性、数据实时性、消息队列的个数等方面的要求很高。

kafka针对海量数据,但是对数据的正确度要求不是十分严格。而阿里巴巴中用于交易相关的事情较多,对数据的正确性要求极高,Kafka不合适

(3)当业务成长到一定规模,采用开源方案的技术成本会变高.

开源方案无法满足业务的需要;旧版本、自开发代码与新版本的兼容都可能是问题;运维角度,Kafka使用 scala 编写,而阿里是java系。Kafka 的后续维护是个问题。

(4)阿里在团队、成本、资源投入等方面约束性条件几乎没有.

综上,阿里选择自己开发RocketMQ更多是业务的驱动,当业务更多的需要以下功能的支持时,kafka 不能满足或者 ActiveMQ 等其他消息中间件不能满足,财大气粗能力又强业务还复杂,所以就自己开发了。

总结:没有银弹,只有最合适

RocketMQ 凭借高吞吐、低延迟、完善的企业级特性,成为阿里系及众多金融、电商企业的首选;Kafka 在大数据领域仍不可替代;RabbitMQ 适合中小规模的灵活路由场景。

选择消息队列时,应从业务规模、可靠性要求、开发成本三个维度综合评估:

  • 中小团队 + 简单需求:RabbitMQ 开箱即用
  • 大数据 + 流式处理:Kafka 生态更成熟
  • 核心业务 + 高可用:RocketMQ 是更稳妥的选择

最后提醒:技术选型没有银弹,建议先做 POC 验证(如用 JMeter 压测),再结合团队技术栈做最终决策。

参考

https://juejin.cn/post/6844903993672482824

https://juejin.cn/post/7532831487114690579

https://juejin.cn/post/6844903815435517960

相关推荐
小股虫1 小时前
RabbitMQ深度解析:从入门到原理再到实战应用
分布式·rabbitmq
CRUD酱1 小时前
RabbitMQ是如何解决消息堆积问题的?
分布式·rabbitmq
写bug的小屁孩1 小时前
2.Kafka-命令行操作、两种消息模型
分布式·kafka
路边草随风1 小时前
java 实现 flink 读 kafka 写 paimon
java·大数据·flink·kafka
小股虫1 小时前
RabbitMQ异步Confirm性能优化实践:发送、消费、重试与故障应对
分布式·性能优化·rabbitmq
小股虫1 小时前
RocketMQ消息可靠性实战:从发送到消费的全流程保障
rocketmq
莫忘初心丶2 小时前
ubuntu24使用docker搭建rabbitmq
docker·rabbitmq
bing.shao2 小时前
Golang 链接kafka 设置SASL_PLAINTEXT安全协议
分布式·安全·kafka
路边草随风2 小时前
java 实现 flink 读 kafka 写 iceberg
java·flink·kafka