Skip to content

本轮 消息中间件面试题库(带答案) ​

生成时间:2026-05-22 22:31


【面试题】1. Kafka 的 ISR 机制是什么?为什么需要 ISR?如何保证数据一致性? ​

【标准答案】ISR 是 In-Sync Replicas,同步副本集合。每个 Partition 都有一个 ISR 列表,包含所有与 Leader 保持同步的副本(包括 Leader 自己)。

为什么需要?传统的主从复制要么全同步(性能差),要么全异步(可能丢数据)。ISR 是折中方案:只让跟得上的副本在 ISR 里,跟不上就踢出去。

数据一致性保证:生产者发送消息时,可以设置 acks 参数。acks=all 意味着消息要写入 ISR 所有副本才算成功。配合 min.insync.replicas 参数,比如设置为 2,即使 ISR 缩小到 1 个副本,也拒绝写入,保证至少有 2 个副本有数据。另外,Kafka 有 HW(高水位)和 LEO(日志末端位移)机制,消费者只能读到 HW 之前的消息,保证不会读到未同步的数据。


【面试题】2. RabbitMQ 的消息确认机制有哪些?ACK、NACK、Reject 分别什么场景用? ​

【标准答案】三种确认方式:

ACK:正常确认,告诉 Broker 消息处理成功,可以删除了。这是最常用的。

NACK:否定确认,消息处理失败,但可以重新入队。第二个参数 requeue=true 会重新放回队列头部,false 则进入死信队列。适用场景:处理失败但值得重试,比如数据库临时不可用。

Reject:拒绝消息,比 NACK 更明确,只能拒绝单条消息。参数 requeue=true 也是重新入队。适用场景:消息格式错误、业务校验失败等明确不该处理的消息。

实际项目中,推荐手动 ACK,避免自动 ACK 导致消息丢失。消费成功就 ACK,失败看情况:临时性失败 NACK + requeue,永久性失败 Reject 进死信队列。


【面试题】3. RocketMQ 的 NameServer 为什么不用 Zookeeper?有什么优势? ​

【标准答案】NameServer 是 RocketMQ 自研的轻量级注册中心,核心设计理念是"极简、无状态"。

不用 Zookeeper 的原因:

第一,Zookeeper 有强一致性保证(ZAB 协议),但 RocketMQ 不需要。Broker 的路由信息不需要强一致,最终一致就够了。NameServer 各节点独立运行,不通信,Broker 向所有 NameServer 注册,客户端随机选一个拉取路由。

第二,Zookeeper 选主逻辑复杂,NameServer 不需要选主,每个节点地位平等,挂了一个不影响其他节点。

第三,Zookeeper 重量级,NameServer 几千行代码就搞定,部署运维简单。

实际优势:轻量、无状态、易扩展、性能高。RocketMQ 的设计哲学是:注册中心不需要强一致,AP 架构比 CP 更适合消息场景。即使 NameServer 全挂,只要 Broker 不重启,客户端本地缓存的路由还能用。


【面试题】4. 消息队列如何保证消息顺序性?举例说明业务场景。 ​

【标准答案】消息顺序性分全局有序和分区有序。

全局有序:整个 Topic 有序,需要单分区、单消费者,性能差,不推荐。

分区有序:同一分区内有序,是实际方案。核心思路:相同业务 ID 的消息发到同一分区。

Kafka:Producer 端通过分区器,根据业务 ID(如订单 ID)哈希取模,保证同一订单的消息进同一分区。Consumer 端单线程消费该分区,或者用内存队列 + 多线程 + 业务 ID 哈希分发,保证同一 ID 的消息串行处理。

RocketMQ:支持顺序消息,发送时指定 MessageQueueSelector,按业务 ID 选队列。消费时用 MessageListenerOrderly 接口,框架保证单线程消费同一队列。

业务场景:订单状态流转(创建→支付→发货→完成),如果乱序可能发货消息先消费,支付后消费,业务异常。再比如数据库 binlog 同步,SQL 执行顺序不能乱。


【面试题】5. 消息积压怎么处理?线上系统突然积压 100 万条消息,你的应急方案是什么? ​

【标准答案】消息积压是生产环境常见问题,分三步走:

第一步,定位原因。是消费者处理慢?还是消费者挂了?还是下游服务不可用?看监控、看日志、看 Consumer 状态。

第二步,临时扩容。核心思路:提高消费速度。如果是消费者处理慢,扩容消费者实例数。但注意:Kafka 消费者数不能超过分区数,RabbitMQ 需要增加队列数或并发数。如果是下游服务瓶颈,先修复下游。

第三步,降级与临时队列。如果下游恢复慢,可以临时创建一个大容量 Topic/队列,用脚本把积压消息转发过去,用多线程快速消费。或者临时修改消费逻辑,只写数据库不调外部服务,快速消化积压。

长期方案:增加分区数、优化消费逻辑、异步处理 + 批量写入、增加熔断降级机制、设置告警阈值。


【面试题】6. RabbitMQ 的死信队列是什么?哪些情况会进入死信? ​

【标准答案】死信队列(DLX,Dead Letter Exchange)是处理"无法被消费的消息"的机制。消息变成死信的三种情况:

第一,消息被拒绝(Reject 或 NACK)且 requeue=false。

第二,消息 TTL 过期。队列或消息本身设置了过期时间。

第三,队列满了。队列达到最大长度,最早的消息会被挤出进入死信。

配置方式:声明队列时指定 x-dead-letter-exchange 参数,指向死信交换机,还可以指定 x-dead-letter-routing-key。

实际应用:订单超时取消(设置 30 分钟 TTL,过期进死信队列,消费死信执行取消逻辑)、失败消息重试几次后转人工处理、消息审计与监控。

死信队列是 RabbitMQ 实现延迟队列的核心手段之一,配合 TTL 使用。


【面试题】7. Kafka 的零拷贝和顺序写是如何提升性能的?底层原理是什么? ​

【标准答案】这两个是 Kafka 高吞吐的核心。

顺序写:磁盘顺序写速度可达 600MB/s,随机写只有 100KB/s。Kafka 把消息追加到日志文件末尾,充分利用顺序写优势。每个 Partition 对应一个文件夹,消息以 Segment 文件形式顺序追加。

零拷贝:传统数据传输是磁盘 → 内核缓冲区 → 用户缓冲区 → 内核 Socket 缓冲区 → 网卡。四次拷贝,四次上下文切换。Kafka 用 sendfile 系统调用,数据直接从磁盘文件描述符到 Socket 描述符,跳过用户空间,只有两次拷贝、两次上下文切换。

配合 mmap(内存映射)和 PageCache:消息先写 PageCache,由操作系统异步刷盘。消费时优先读 PageCache,直接命中就无需读磁盘。

实际效果:单机百万级 TPS,延迟毫秒级。


【面试题】8. RocketMQ 的事务消息原理是什么?如何实现分布式事务? ​

【标准答案】RocketMQ 事务消息基于"半消息"机制,核心流程四步:

第一步,发送半消息。Producer 发送一条"半消息"到 Broker,消息暂时不可消费,状态为"预提交"。

第二步,执行本地事务。Producer 执行本地数据库操作,比如扣款。

第三步,提交或回滚。本地事务成功,发送 Commit 消息,半消息变为可消费;本地事务失败,发送 Rollback 消息,删除半消息。

第四步,事务回查。如果 Producer 宕机或超时未反馈,Broker 定期回查 Producer 事务状态,Producer 查询本地数据库,返回 Commit 或 Rollback。

实现分布式事务的保证:半消息与本地事务是原子的。即使 Producer 宕机,Broker 会回查,保证最终一致性。下游消费者通过消费消息执行远程事务,失败就重试。

适用场景:支付成功后发券、订单创建后扣库存,强依赖最终一致性的业务。


【面试题】9. 如何设计一个百万级 TPS 的消息系统?从架构角度分析。 ​

【标准答案】百万级 TPS 需要全链路优化,从生产端、Broker、消费端三个层面:

生产端:异步发送、批量发送、消息压缩、合理设置分区数(Kafka 单分区 5-10 万 TPS,需要 10-20 个分区)、客户端连接池复用。

Broker 端:多节点集群、分区副本合理分配(ISR 机制)、顺序写 + 零拷贝、批量刷盘(异步刷盘)、压缩算法(LZ4 或 Zstd)、合理配置 JVM 和内存池(Kafka 用堆外内存,RocketMQ 用 mmap)。

消费端:消费者实例数 >= 分区数、多线程消费、批量拉取、异步处理 + 本地缓存、下游用批量写入(如批量插数据库)。

网络与硬件:万兆网卡、SSD 磁盘、多网卡绑定、关闭 Swap、文件系统用 XFS 或 Ext4。

监控与运维:全链路监控(Prometheus + Grafana)、告警、容量规划、灰度扩容、限流熔断。

核心思想:充分利用顺序写、零拷贝、批量处理,减少网络 IO 和磁盘随机访问。


【面试题】10. RabbitMQ、Kafka、RocketMQ 如何选型?各自适用场景是什么? ​

【标准答案】从四个维度对比:

吞吐量:Kafka > RocketMQ > RabbitMQ。Kafka 百万级,RocketMQ 十万级,RabbitMQ 万级。

延迟:RabbitMQ 最低(微秒级),RocketMQ 毫秒级,Kafka 毫秒级但吞吐高。

功能丰富度:RabbitMQ 最丰富(路由灵活、多种 Exchange、延迟队列、优先级队列),RocketMQ 次之(事务消息、延迟消息、消息过滤),Kafka 最简单(核心功能强,扩展靠生态)。

可靠性:RocketMQ 同步刷盘 + 同步复制最可靠,Kafka 配合 acks=all 也可靠,RabbitMQ 持久化 + 镜像队列可用。

适用场景:

RabbitMQ:业务系统异步解耦、延迟任务、复杂路由、小规模消息(万级)、需要低延迟和丰富特性。

Kafka:日志收集、大数据管道、流处理、高吞吐场景(百万级)、需要长期存储和回溯。

RocketMQ:金融级可靠性、分布式事务、电商订单、需要事务消息和精确一次语义。

选型建议:小项目用 RabbitMQ,大数据用 Kafka,金融电商用 RocketMQ。国内生态 RocketMQ 更好,开源社区活跃,阿里系支持。