Skip to content

消息中间件面试题库 ​

生成时间:2026-05-21 22:09


【面试题】1. Kafka的ISR机制是什么?为什么需要ISR?同步延迟怎么处理? ​

【标准答案】ISR(In-Sync Replicas)是Kafka中与Leader保持同步的副本集合。每个Partition有一个Leader和多个Follower,只有ISR中的副本才有资格被选为新Leader。

为什么需要ISR?

  • 纯同步复制:一条消息要所有副本都确认才算写入成功,性能差
  • 纯异步复制:Leader挂了可能丢数据
  • ISR是折中方案:只要ISR中的副本同步了就认为成功,兼顾性能和可靠性

同步延迟怎么处理?

  • replica.lag.time.max.ms:默认30秒,超过这个时间没同步的副本会被踢出ISR
  • 生产者设置acks=all,消息必须被ISR所有副本确认
  • 监控ISR收缩告警,ISR过少时及时排查网络或磁盘问题

【面试题】2. RabbitMQ的四种Exchange类型分别适用什么场景?路由键怎么设计? ​

【标准答案】四种Exchange类型:

类型路由规则适用场景
Direct精确匹配routing key点对点、订单状态通知
Fanout广播到所有绑定队列群发通知、缓存刷新
Topic通配符匹配(* #)多条件过滤、日志分级
Headers匹配消息头键值对复杂条件路由(少用)

路由键设计建议:

  • Direct:用业务ID,如order.created、user.login
  • Topic:用层次结构,如order.*.paid、log.#
  • Fanout:不需要routing key
  • 避免routing key过长,影响匹配性能

【面试题】3. RocketMQ的事务消息原理是什么?如何保证分布式事务一致性? ​

【标准答案】事务消息原理(半消息机制):

  1. 发送半消息:Producer发一条"半消息"到Broker,消费者不可见
  2. 执行本地事务:Producer执行本地数据库操作
  3. 提交/回滚:根据本地事务结果,向Broker发送提交或回滚指令
  4. 回查机制:如果Broker没收到确认,会定时回查Producer事务状态

如何保证一致性?

  • 半消息+本地事务+确认三步是原子的
  • 回查机制解决Producer宕机后的事务状态丢失
  • 消费端通过幂等性保证不重复消费

适用场景:

  • 跨系统的最终一致性事务
  • 订单创建+库存扣减+积分发放等链路

【面试题】4. 消息积压了怎么处理?生产端和消费端分别怎么优化? ​

【标准答案】消息积压应急处理四步走:

  1. 快速定位:看监控面板,确认是哪个Topic/队列积压
  2. 临时扩容:增加Consumer实例数,提升消费速度
  3. 批量消费:改为批量拉取+批量处理
  4. 降级策略:非核心消息丢弃或延迟处理

生产端优化:

  • 限流:控制消息发送速率
  • 压缩:减少网络传输量
  • 批量发送:Kafka天然支持,RabbitMQ用批量confirm

消费端优化:

  • 增加分区数(Kafka)或队列数(RabbitMQ)
  • 提高并发度:Kafka的max.poll.records,RabbitMQ的prefetch
  • 异步处理:消息接收入库,后台异步消费
  • 跳过积压消息:极端情况下,重置offset到最新

【面试题】5. Kafka的零拷贝是怎么实现的?为什么比传统IO快? ​

【标准答案】传统IO流程(4次拷贝,4次上下文切换): 磁盘 → 内核缓冲区 → 用户缓冲区 → 内核Socket缓冲区 → 网卡

Kafka零拷贝(sendfile,2次拷贝,2次切换): 磁盘 → 内核缓冲区 → 网卡

实现原理:

  • Linux的sendfile系统调用,数据直接从文件描述符传输到Socket
  • DMA直接传输,绕过用户空间
  • Kafka消息存放在PageCache,发送时直接从内存到网络

为什么快?

  • 减少数据拷贝次数(4次→2次)
  • 减少上下文切换(4次→2次)
  • 减少CPU参与,DMA直接完成传输

配合顺序写:

  • Kafka消息顺序追加到日志文件
  • 磁盘顺序写速度可达600MB/s,远超随机写

【面试题】6. RabbitMQ如何实现延迟队列?有哪些方案? ​

【标准答案】方案一:TTL + 死信队列(DLX)

消息 → 普通队列(设置TTL)→ 过期 → 死信队列(DLX)→ 消费者
  • 消息设置TTL,过期后自动进入死信队列
  • 缺点:先进先出,第一个消息TTL最长会阻塞后面的消息

方案二:rabbitmq_delayed_message_exchange插件

bash
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
  • 消息带上x-delay头,延迟指定时间后路由到队列
  • 优点:消息独立延迟,互不阻塞
  • 缺点:需要安装插件

方案三:外部定时任务调度

  • Redis的ZSet + 定时扫描
  • XXL-JOB等定时任务框架
  • 适用:延迟任务量大且复杂

选型建议:

  • 简单延迟:TTL+DLX
  • 灵活延迟:插件
  • 大规模延迟任务:Redis+定时任务

【面试题】7. 消费端幂等性如何设计?有哪些去重方案? ​

【标准答案】幂等性概念: 同一条消息被消费多次,结果与消费一次相同。

去重方案:

方案实现方式优点缺点
唯一ID+数据库消息ID做唯一索引简单可靠性能差
唯一ID+RedisSETNX去重高性能依赖Redis
乐观锁版本号更新无额外存储需业务支持
状态机订单状态流转业务语义强适用场景有限

推荐方案:唯一ID + Redis + 数据库兜底

java
// 1. Redis去重
if (redis.setnx(msgId, "1", 24h)) {
    // 2. 数据库唯一索引兜底
    try {
        process(msg);
    } catch (DuplicateKeyException e) {
        // 已处理过,忽略
    }
}

关键点:

  • 消息必须有唯一ID(Kafka的offset + partition + topic组合,RocketMQ的msgId)
  • Redis过期时间要大于消息处理周期
  • 数据库唯一索引是最后一道防线

【面试题】8. RabbitMQ和Kafka的架构差异是什么?选型时怎么选? ​

【标准答案】架构对比:

维度RabbitMQKafka
设计理念智能路由Broker日志存储系统
消息模型Queue + ExchangeTopic + Partition
消息存储内存为主磁盘顺序写
消费模式推模式(Push)拉模式(Pull)
消息确认ACK/NACKOffset提交
吞吐量万级/秒十万~百万级/秒
延迟微秒级毫秒级
消息堆积内存有限磁盘海量存储

选型建议:

选RabbitMQ:

  • 消息量小(<10万/秒)
  • 需要复杂路由规则
  • 要求延迟极低
  • 需要事务消息、延迟队列

选Kafka:

  • 消息量大(>10万/秒)
  • 需要消息回溯、持久化
  • 日志收集、大数据管道
  • 流式计算(Kafka Streams)

RocketMQ:

  • 阿里出品,适合电商场景
  • 事务消息、延迟消息功能强
  • 国内社区活跃

【面试题】9. Kafka的Consumer Group重平衡协议是什么?如何避免重平衡风暴? ​

【标准答案】重平衡协议: 当Consumer Group中消费者变化或Topic分区数变化时,重新分配分区给消费者的过程。

触发条件:

  • 新消费者加入
  • 消费者宕机或主动退出
  • Topic分区数变化
  • 消费者心跳超时(session.timeout.ms)

重平衡流程:

  1. 消费者请求加入Group
  2. 选出Coordinator(Group Leader)
  3. Leader分配分区方案
  4. 所有消费者同步新方案
  5. 开始消费

重平衡风暴: 频繁重平衡导致消费暂停,吞吐量骤降。

如何避免?

  • 增大session.timeout.ms(默认10s → 30s+)
  • 增大max.poll.interval.ms(处理时间不足会触发重平衡)
  • 减少Consumer数量变化(容器化环境固定实例数)
  • 使用静态成员(group.instance.id)

监控告警:

  • 监控重平衡次数和耗时
  • 消费延迟告警

【面试题】10. 如果Kafka消息丢失了,怎么排查?全链路怎么保证不丢? ​

【标准答案】全链路消息丢失风险点:

环节风险解决方案
生产者发送失败未确认acks=all + 重试
Broker副本未同步min.insync.replicas=2
Broker刷盘前宕机unclean.leader.election.enable=false
消费者处理失败但提交offset先处理再提交

排查步骤:

  1. 生产端排查:

    • 检查是否有发送失败日志
    • 确认是否开启acks=all
    • 检查重试次数和超时配置
  2. Broker端排查:

    • 检查ISR列表是否正常
    • min.insync.replicas配置
    • 磁盘空间、网络抖动
  3. 消费端排查:

    • 检查offset提交时机
    • 是否有消费异常但提交了offset

最佳实践配置:

properties
# 生产者
acks=all
retries=3
enable.idempotence=true

# Broker
min.insync.replicas=2
unclean.leader.election.enable=false

# 消费者
enable.auto.commit=false
# 手动提交offset

总结一句话: 生产者确认、Broker多副本同步、消费者先处理再提交。


本轮题目覆盖: ISR机制、Exchange路由、事务消息、消息积压处理、零拷贝原理、延迟队列、消费幂等、架构选型、重平衡协议、消息丢失排查