这篇文章资料来自于网络,是对部分知识整理,这里只是记录一下,仅供参考
一、架构设计:谁的底层更能打?
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 的场景
- 金融级业务:需要事务消息、高可靠性的支付、订单系统
- 大规模集群:如电商平台的双 11 峰值流量(百万级 TPS 需求)
- 复杂业务路由:需要 - tag 过滤、定时消息等高级特性
- 国产化需求:对开源协议(Apache v2)和社区响应速度有要求
考虑 Kafka 的场景
- 日志采集:ELK 生态的标配,适合海量日志的异步传输
- 大数据场景:与 Spark、Flink 等计算框架集成更成熟
- 流式处理:需要基于消息的实时计算能力
选择 RabbitMQ 的场景
- 中小规模应用:如内部系统的通知、告警功能
- 复杂路由需求:需要灵活的交换机路由规则
- 快速原型开发:部署简单,开箱即用
五、踩坑经验:从实战中总结的教训
- RocketMQ 的 NameServer 高可用:
单节点 NameServer 存在单点风险,生产环境需部署 3 + 节点,Producer/Consumer 配置多个 NameServer 地址(用分号分隔)
- Kafka 的分区数量陷阱:
分区数并非越多越好,每个分区都会占用内存和文件句柄,建议单个 Broker 的分区总数不超过 2000
- 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