RabbitMQ 与 Kafka 对比
约 1270 字大约 4 分钟
布欧-Lewyon
2026-05-17
首页 › Spring Boot › 消息与集成 › RabbitMQ 与 Kafka 对比
建议先阅读 RabbitMQ 集成 和 Kafka 集成,熟悉基本用法后再看对比。
RabbitMQ 和 Kafka 的设计哲学完全不同——RabbitMQ 是消息代理(Message Broker),Kafka 是分布式日志(Distributed Log)。选错中间件的代价很高,本节从架构、功能、运维、选型四个维度做系统化对比,并给出两者结合使用的架构模式。
架构对比
| 维度 | RabbitMQ | Kafka |
|---|---|---|
| 消费方式 | Push:Broker 主动推给消费者 | Poll:消费者主动拉取 |
| 消息存储 | ACK 后删除 | 按保留策略保留(时间/大小),不因消费删除 |
| 消息顺序 | 单队列单消费者有序 | 单分区有序 |
| 路由机制 | Exchange 四种路由 | Key 哈希 / 轮询分配到 Partition |
| 吞吐量 | 万级/秒 | 百万级/秒 |
| 延迟 | 微秒级(内存模式) | 毫秒级(刷盘 + ISR 复制) |
| 持久化 | 内存 + 磁盘可配 | 全部磁盘 |
| 消息回溯 | 不支持(ACK 后消失) | 原生支持(重置 Offset) |
功能对比
| 能力 | RabbitMQ | Kafka |
|---|---|---|
| 延时消息 | 原生(TTL + DLX + 插件) | 需自实现 |
| 死信机制 | 原生死信 Exchange | DLT Topic + 自定义 Recoverer |
| 优先级队列 | 原生支持 | 近似实现 |
| 消费确认 | 逐条 ACK | 批量 Offset 提交 |
| 管理 UI | 开箱自带(15672) | 需第三方工具 |
| 流处理 | 无 | 内置 Kafka Streams / ksqlDB |
| 客户端生态 | 几乎所有语言有 AMQP 客户端 | 官方 Java 最成熟 |
选型决策树
结合使用:混合架构
大型系统往往同时使用 RabbitMQ 和 Kafka——两者分工明确,互补而非互斥。
典型混合架构
Spring Boot 双 MQ 集成
@Configuration
public class DualMqConfig {
// RabbitMQ:处理业务消息
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory cf) {
return new RabbitTemplate(cf);
}
// Kafka:处理事件流转发
@Bean
public KafkaTemplate<String, Object> kafkaTemplate(ProducerFactory<String, Object> pf) {
return new KafkaTemplate<>(pf);
}
}@Service
public class OrderService {
private final RabbitTemplate rabbitTemplate;
private final KafkaTemplate<String, Object> kafkaTemplate;
@Transactional
public void createOrder(Order order) {
// ① 数据库保存订单
orderRepository.save(order);
// ② RabbitMQ:发通知给下游业务服务(实时、可靠)
rabbitTemplate.convertAndSend("order.exchange", "order.created", order);
// ③ Kafka:写入事件流(供数据平台消费、回溯)
kafkaTemplate.send("order-events", order.getOrderNo(), order);
}
}// RabbitMQ 消费者——处理实时业务(低延迟)
@Component
public class OrderNotifyConsumer {
@RabbitListener(queues = "order.create.queue")
public void handle(@Payload Order order, Channel ch, @Header(AmqpHeaders.DELIVERY_TAG) long tag) {
try {
notificationService.sendSms(order.getUserId(), "订单创建成功");
ch.basicAck(tag, false);
} catch (Exception e) {
ch.basicNack(tag, false, true);
}
}
}
// Kafka 消费者——处理数据流(可回溯、高吞吐)
@Component
public class OrderEventConsumer {
@KafkaListener(topics = "order-events", groupId = "order-data-group")
public void handle(@Payload Order order, Acknowledgment ack) {
dataWarehouseService.syncOrder(order);
ack.acknowledge();
}
}分层责任对比
| 层 | 中间件 | 职责 | 延迟要求 | 数据保留 |
|---|---|---|---|---|
| 业务层 | RabbitMQ | 订单通知、支付回调、任务分发 | 毫秒级 | 秒级(消费即删) |
| 数据层 | Kafka | 事件溯源、报表同步、CDC、日志采集 | 秒级 | 天/周级(可回溯) |
常见误区
- "Kafka 比 RabbitMQ 好" ——没有银弹。RabbitMQ 在业务消息领域(低延迟、灵活路由、延迟消息)仍然是更好的选择。
- "RabbitMQ 不支持高吞吐" ——合理配置下可达数万 TPS,只是和 Kafka 的百万级不在一个量级。
- "Kafka 消息不会丢" ——
acks=all+min.insync.replicas=2做到不丢,但单副本下 Broker 宕机仍会丢数据。 - "用了消息队列就能解耦" ——只解耦了通信,不解耦数据模型。上下游消息格式需有契约治理。
迁移成本
| 方向 | 最大挑战 |
|---|---|
| RabbitMQ → Kafka | Push 改 Poll,消费者模型变化大;消息回溯思维转变 |
| Kafka → RabbitMQ | Offset 管理习惯改 ACK 模式;无法回溯历史消息 |
生产意识:如果团队不确定,优先选 RabbitMQ(门槛低、运维简单)。当出现明确的高吞吐(万级以上)、回溯需求、流处理需求时再引入 Kafka。
小结
- RabbitMQ:Push 模型、Exchange 路由、低延迟、万级吞吐——适合业务消息。
- Kafka:Poll 模型、Partition 日志、可回溯、百万级吞吐——适合数据管道与事件流。
- 大型系统可两者共存:RabbitMQ 管实时业务,Kafka 管数据流与事件溯源。
- 不存在更好的中间件,只有更适合当前场景的中间件。
上一节:Kafka 集成
下一节:安全入门
