面试知识库
高 进阶

MQ选型对比#

一句话答案#

Kafka 高吞吐适合日志/大数据,RocketMQ 功能全适合业务消息(事务/延迟),RabbitMQ 轻量低延迟适合小规模。

核心要点

主流 MQ 对比(以 2026 年各自主线版本为准)#

维度Kafka(4.x)RocketMQ(5.x)RabbitMQ(4.x)Pulsar
定位高吞吐日志/流处理业务消息轻量业务消息、复杂路由云原生消息+流,多租户
单机吞吐(量级)百万级十万级万级十万~百万级
架构Broker + KRaft(4.0 起移除 ZK)NameServer + Broker,5.x 可加无状态 ProxyErlang 节点集群Broker 无状态 + BookKeeper 存储,计算存储分离
事务有,面向 Exactly-Once 流处理,不是半消息半消息 + 回查(业务事务)仅 AMQP 0-9-1 通道事务(很慢),常用 Publisher Confirm有事务 API(跨 Topic 原子写/确认)
延迟消息不原生支持4.x 18 个固定级别;5.x 任意时间(有最长时长上限,可配置)靠 TTL+死信或延迟插件原生支持任意延迟投递
死信队列无原生(Kafka Connect/Streams 或框架如 Spring Kafka 实现)原生(%DLQ% + 消费组)原生(DLX 死信交换机)原生(DLQ Topic)
队列语义消费者组按分区独占;4.2 起共享组(Queues for Kafka)生产可用5.x POP 消费,按消息分摊天然队列Shared/Key_Shared 订阅
高可用多副本 ISR主从 / 5.x Controller 自动切主4.0 起移除经典镜像队列,改用 Quorum Queue(Raft)BookKeeper 多副本

选型结论:日志、埋点、CDC、流计算选 Kafka;电商订单、支付等要事务消息/延迟消息/重试死信的业务选 RocketMQ;规模不大、要灵活路由选 RabbitMQ;多租户、跨地域复制、存储要独立扩展时考虑 Pulsar。

选型差异点:消费失败怎么处理#

消费失败的处理策略:

1. 重试机制

第一次失败 → 等待 5s 重试
第二次失败 → 等待 30s 重试
第三次失败 → 等待 1min 重试
...
达到最大重试次数 → 投递到死信队列

(指数退避策略,避免频繁重试打爆下游)
plaintext

2. 死信队列(Dead Letter Queue,DLQ)

死信队列是专门存放”处理失败”消息的队列,消息进入死信队列的条件:

① 消息消费失败且超过最大重试次数
② 消息在队列中等待超过 TTL(消息过期)
③ 队列长度超过上限(消息被挤出)
plaintext

RocketMQ 的死信队列:

// 消费失败达到最大重试次数(默认16次)后,自动投入死信队列
// 死信 Topic 名称:%DLQ%消费者GroupID

// 监控和处理死信:
consumer.subscribe("%DLQ%MyConsumerGroup", "*");
consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
    // 告警、人工处理、记录到 DB 等
    alertService.sendAlert(msgs.get(0));
    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
});
java

Kafka 的死信队列(需自己实现):

处理死信的策略:

  1. 人工介入:告警 → 运营人员在控制台查看死信 → 手动重新处理
  2. 自动重试:定时任务将死信重新投递(配合幂等性)
  3. 降级处理:记录到数据库,由补偿任务处理

面试回答(2分钟版)

MQ 选型主要看三款:Kafka 吞吐量最高,单机百万级 TPS,基于磁盘顺序写和零拷贝,适合日志采集、大数据实时计算等高吞吐场景,但业务功能相对简单:没有原生延迟消息和死信队列,它的事务面向流处理的 Exactly-Once,不是 RocketMQ 那种半消息加回查的业务事务。RocketMQ 是阿里开源的,功能最全面,原生支持事务消息、延迟消息(5.x 支持任意时间延迟)、顺序消息、死信队列,适合电商订单、金融业务等对可靠性和功能要求高的场景,吞吐量十万级也不差。RabbitMQ 基于 Erlang 开发,轻量低延迟,路由机制灵活,适合小规模业务和消息量不大的场景,但集群扩展能力不如前两者,4.0 起高可用要用基于 Raft 的 Quorum Queue,经典镜像队列已移除。消费失败的处理也是面试重点:一般采用指数退避重试策略,第一次 5 秒、第二次 30 秒依次递增,超过最大重试次数后投入死信队列。RocketMQ 原生支持死信队列,Kafka 需要自己实现重试 Topic 和死信 Topic。死信消息的处理方式包括告警人工介入、定时任务自动重投、或降级记录到数据库由补偿任务处理。

追问与易错

追问方向:

  • “Kafka 和 RocketMQ 怎么选?”→ Kafka 适合大数据/日志/流处理场景,吞吐极高但功能相对简单;RocketMQ 适合业务消息场景,支持事务消息、延迟消息、死信队列等丰富功能,国内电商用得多
  • “RabbitMQ 适合什么场景?”→ RabbitMQ 基于 Erlang 天然高可用,支持多种路由模式(direct/topic/fanout),适合中小规模系统和需要复杂路由的场景;单机吞吐(万级)低于 Kafka(百万级)
  • “公司没有运维团队怎么选 MQ?”→ 优先考虑云服务(阿里云 RocketMQ、AWS SQS/Kinesis)免运维;自建的话 RabbitMQ 部署简单文档齐全,Kafka 运维成本相对较高需要专人维护

易错点:

  • ❌ 选型只比压测吞吐——还要看团队运维能力、语言生态、有没有云托管、需要哪些功能(事务消息、延迟、回溯、顺序);缺功能自己补的成本通常比吞吐差距更大
  • ❌ RabbitMQ 容易丢消息——开启 publisher confirm、消息持久化、Quorum Queue 和手动 ack 后同样可靠,丢消息多半是配置问题
  • ❌ Kafka 适合所有业务消息场景——Kafka 没有原生延迟消息和死信,逐条确认要到 4.2 的共享组才有;业务事件场景往往要自己补这些