在微服务系统里,MQ 往往不是“锦上添花”,而是系统韧性的基础设施:削峰、解耦、异步化、事件驱动、数据同步,很多链路都绕不开它。
但 MQ 选型最容易陷入一个误区:只问“哪个性能最好”。真正的问题应该是:你的业务更需要低延迟、强路由、事务消息、消息回溯,还是海量吞吐?
一、主流 MQ 快速对比
| MQ |
核心定位 |
优势 |
短板 |
典型场景 |
| RabbitMQ |
传统消息代理,AMQP 生态成熟 |
路由模型强,延迟低,管理工具完善,适合业务消息 |
超大吞吐和长时间堆积不是传统强项,集群和高可用需要仔细设计 |
订单状态流转、通知、任务队列、复杂路由 |
| Kafka |
分布式事件流平台 |
高吞吐、可持久化、可回放、生态强,适合日志和事件流 |
运维复杂度较高,只保证分区内有序,小消息低延迟场景不一定最优 |
日志采集、数据管道、用户行为流、实时计算 |
| RocketMQ |
面向业务消息和金融级场景 |
事务消息、顺序消息、延迟消息支持好,业务语义丰富 |
国际生态弱于 Kafka,部分语言和工具链成熟度有差异 |
交易链路、订单系统、支付状态同步 |
| Pulsar |
云原生消息与流平台 |
存储计算分离,多租户、跨地域复制、分层存储能力强 |
架构组件更多,引入和运维门槛较高 |
多租户平台、跨地域消息、海量 Topic |
| Redis Streams |
Redis 内置流数据结构 |
简单、低延迟、接入成本低,适合轻量消息流 |
不是完整 MQ 替代品,大规模持久化和复杂治理能力有限 |
小规模事件流、缓存旁路、轻量异步任务 |
一句话总结:
业务消息优先看 RabbitMQ / RocketMQ。
日志、事件流、数据平台优先看 Kafka。
云原生多租户和超多 Topic 可以看 Pulsar。
已有 Redis 且场景轻量,可以用 Redis Streams。
二、优劣势展开讲
1. RabbitMQ:业务系统里的“精细派”
RabbitMQ 最大的特点是路由能力强。它通过 Exchange、Queue、Binding Key 组合,可以轻松实现直连、广播、主题匹配等模式。
优点是业务表达力强,管理界面友好,适合中后台系统、任务分发和状态通知。缺点是如果你要承载海量日志、长时间消息堆积、反复回放,传统队列模型会吃力。RabbitMQ 也有 Streams,但这更像是补齐事件流能力,而不是替代所有队列场景。
2. Kafka:吞吐和回放能力的“基础设施派”
Kafka 的核心不是“队列”,而是“分区追加日志”。消息写入 Topic 的某个 Partition 后,会按 Offset 顺序保存。消费者读到哪里,由消费位点控制,所以天然支持消息回放。
它适合做事件总线、日志管道、实时计算入口。缺点也很明确:模型偏基础设施,开发和运维都需要理解分区、副本、ISR、ACK、重平衡、保留策略等概念。
3. RocketMQ:更贴近交易业务
RocketMQ 在国内业务系统里很常见,原因是它对“业务消息”的支持更直接,比如事务消息、顺序消息、延迟消息、消息轨迹等能力。
如果系统里有大量订单、支付、履约、库存这类链路,RocketMQ 的语义会比 Kafka 更贴业务。短板是国际生态、周边工具和社区规模通常不如 Kafka。
4. Pulsar:云原生和多租户优先
Pulsar 的架构亮点是 Broker 和存储层分离,底层依赖 BookKeeper 做持久化。它在多租户、跨地域复制、分层存储、海量 Topic 方面很有优势。
代价是架构复杂度更高。对中小团队来说,如果只是普通业务异步,Pulsar 可能偏重。
5. Redis Streams:轻量,但别滥用
Redis Streams 很适合“我已经有 Redis,只想快速做一点消息流”的场景。它支持追加写、消费组、ACK,使用体验直接。
但它不是完整 MQ 的平替。涉及强可靠、大规模堆积、复杂重试、跨机房治理时,还是应该选择专业 MQ。
三、怎么选?给一个落地判断
如果你的系统是典型微服务业务系统,消息量中等,强调路由、死信、重试、低延迟,可以选 RabbitMQ。
如果你要建设日志平台、实时数仓、埋点流、事件驱动平台,选 Kafka 更稳。
如果你在做交易、支付、订单、库存这类强业务链路,并且需要事务消息、延迟消息,RocketMQ 很合适。
如果你是云平台、多租户 SaaS、跨地域消息系统,并且团队能承接复杂运维,可以评估 Pulsar。
如果只是轻量异步任务,且已有 Redis,可以用 Redis Streams,但要克制。
四、源码讲解:Kafka Producer 一条消息是怎么发出去的?
这里选 Kafka 来拆源码,因为它的核心设计非常典型:客户端批量写入、后台线程发送、Broker 追加日志。你如果正在探索 后端 & 架构 中的高并发与分布式系统设计,这个链路拆解会很有参考价值。
Kafka Producer 的发送链路可以简化成:
KafkaProducer.send()
-> doSend()
-> RecordAccumulator.append()
-> Sender.runOnce()
-> NetworkClient.send()
-> Broker KafkaApis.handleProduceRequest()
-> ReplicaManager.appendRecords()
-> 写入分区日志
1. send:用户线程并不直接发网络请求
在 KafkaProducer 里,send() 是异步方法。它做的第一件事不是立刻把消息发到 Broker,而是先进入本地缓冲区。
关键逻辑包括:
producer.send(new ProducerRecord<>("topic", key, value), callback);
内部大致会做几件事:
执行拦截器 ProducerInterceptor
等待 Topic 元数据
序列化 key 和 value
计算目标分区
将消息写入 RecordAccumulator
必要时唤醒后台发送线程 Sender
这就是 Kafka Producer 高吞吐的关键:用户线程主要负责“生产”和“入队”,真正的网络发送交给后台线程批量处理。
2. RecordAccumulator:批量发送的核心
RecordAccumulator 可以理解为 Producer 端的本地缓冲池。它按 TopicPartition 维度维护待发送批次。
结构可以抽象成:
TopicPartition -> Deque<ProducerBatch>
也就是说,每个分区都有自己的批次队列。新消息进来时,Kafka 会优先尝试追加到当前批次;如果批次满了,或者没有可用批次,就创建新的 ProducerBatch。
这也解释了几个常见参数:
batch.size:单个批次的目标大小
linger.ms:批次没满时最多等多久
buffer.memory:Producer 总缓冲内存
compression.type:批次级压缩,通常能显著提升吞吐
所以 Kafka 的高吞吐不是靠“单条消息发送得快”,而是靠“把很多消息凑成批,一次发出去”。
3. Sender:真正干活的后台线程
Sender 是 Producer 的 I/O 线程。它循环执行 runOnce(),核心动作是:
检查哪些分区的 batch 可以发送
按 Broker 节点聚合 batch
构造 ProduceRequest
通过 NetworkClient 发出请求
处理 ProduceResponse
完成 Future 和 Callback
这一步非常关键:Kafka 不是按消息逐条发,而是按 Broker 聚合请求。一个请求里可能包含多个 TopicPartition 的多个批次。
这也是为什么 Kafka 在高吞吐场景下表现非常好:它减少了网络请求次数,也让磁盘顺序写更充分。
4. Broker:收到 ProduceRequest 后追加日志
Broker 侧入口在 KafkaApis.handleProduceRequest()。
大致流程是:
校验请求权限
校验 Topic / Partition
校验消息格式
调用 ReplicaManager 写入
根据 acks 判断何时返回响应
如果配置是:
acks=all
那么 Leader 写入本地日志后,还要等待 ISR 副本同步到要求的位置,才会认为这条消息真正提交成功。
所以 Kafka 的可靠性不是单点写入,而是由 Leader、Follower、ISR、副本确认机制共同保证。这也是为什么在深度使用 Kafka 这类中间件时,理解其复制协议至关重要。
五、Kafka 的设计精髓
Kafka Producer 的源码链路背后,其实是三个设计思想:
第一,用户线程和网络线程分离。
send() 快速返回,后台线程统一发送,减少阻塞。
第二,按分区批量缓存。
RecordAccumulator 让小消息变成批量请求,提高吞吐。
第三,日志追加模型。
Broker 侧顺序追加日志,结合 Offset、Retention 和副本机制,实现高吞吐、可回放和高可靠。
这也是 Kafka 和传统 MQ 最大的差异:它不是把消息“消费掉就删除”,而是把消息作为事件日志保留下来,让不同消费者按自己的节奏读取。感兴趣的话,可以去 开源实战 板块深挖这些顶尖项目的设计哲学。
六、最后给一个选型建议
MQ 没有银弹,只有匹配。
做业务异步,先看 RabbitMQ 或 RocketMQ。
做数据流和事件平台,Kafka 依然是最稳的选择。
做云原生多租户消息平台,再认真评估 Pulsar。
做轻量内部队列,Redis Streams 可以快速解决问题。
如果只能记住一句话:
RabbitMQ 更像“消息路由器”,RocketMQ 更像“业务消息引擎”,Kafka 更像“事件流存储系统”,Pulsar 更像“云原生消息平台”。
参考资料:
- Apache Kafka 官方介绍
- RabbitMQ Queues 官方文档
- Apache RocketMQ 官方网站
- Apache Pulsar 官方网站
- Apache Kafka 源码仓库