跳到主要内容

消息队列

消息队列在生产者与消费者之间保存并传递工作。本文比较 Kafka 4.1 普通消费者组与 RabbitMQ 4.1 队列。范围是日志、路由、保留与选型。

1. 面试核心​

先记住这几条,再读正文
  • Kafka 日志模型。 Kafka 按 partition 保存日志,普通消费组用 offset 管理进度。卡 · Kafka 分区日志
  • RabbitMQ 路由模型。 RabbitMQ exchange 根据 binding 将消息路由到 queue。
  • 保留与重放。 Kafka 的日志保留独立于消费进度,compact 按键保留最新状态。卡 · 保留与日志压缩
  • 消费组分工。 普通消费组内,一个 partition 同时分配给一个消费者。
  • 削峰容量。 削峰依赖队列容量与消费余量,持续入流超出消费能力会积压。

2. 消息队列的作用​

生产者发布工作后,消费者按容量异步处理。队列吸收短时速率差,也隔离部分服务故障。代价是结果延迟和新的失败恢复流程。

异步发布后,业务需区分已接收、已处理和最终完成。接口可以返回任务标识,再提供结果查询。

3. Kafka 分区日志​

topic 包含多个 partition。record 在分区中按 offset 排列。消费读取不删除记录,清理策略决定保留范围。

普通 consumer group 独立保存消费进度。不同组可以各自读取同一份数据。同组一个 partition 同时分配给一个 consumer。消费者多于分区时,多出的消费者空闲。

本节讨论 KafkaConsumer 的普通消费者组。Kafka 4.1 的 Share Groups 使用另一套共享投递机制。它不适用上述独占分区的消费模型。

4. RabbitMQ 路由​

生产者将消息发布到 exchange。exchange 根据类型、routing key 和 binding 选择队列。一个发布可进入多个已匹配队列。

exchange 类型匹配方式
directrouting key 精确匹配 binding key。
topic按点分词匹配,* 匹配一个词,# 匹配零个或多个词。
fanout路由到所有绑定队列。
headers按头部属性和匹配规则选择队列。

同一队列的多个消费者分担消息。多个独立业务组应使用各自队列。常规队列消息确认后可删除;RabbitMQ Streams 则采用保留日志模型。

5. 消费进度​

Kafka 的 position 是下一条待返回的记录位置。committed offset 是故障恢复使用的位置。手动提交时,应提交连续完成范围之后的下一个位置。

RabbitMQ 手动确认模式保留未确认投递状态。Channel 或连接关闭后,未确认消息会重新入队。确认具体时机见消息可靠性。

6. 保留与日志压缩​

Kafka topic 的 cleanup.policy=delete 按时间或大小清理 segment。消费者落后过久时,所需旧数据会被清除。重放范围受保留策略约束。

cleanup.policy=compact 在后台保留各键的较新记录。压缩保留记录顺序和原 offset,清理后 offset 可以有空洞。键对应的 null 值是删除标记,即 tombstone。

tombstone 也有保留期限。落后太久的消费者会错过删除标记。因此压缩日志适合恢复最新键状态,完整历史审计需另行保留事件。

7. 消息顺序​

Kafka 分区内按 offset 有序。业务完成顺序还取决于分区映射和消费并发。重复、重新入队和版本处理见消息幂等性。

8. 投递语义​

语义结果约束
At-most-once每条至多处理一次,失败允许漏处理。
At-least-once保证重试交付,消费者要接受重复。
Exactly-once在明确定义的提交边界内产生一次有效结果。

交付保证依赖持久化、保留和恢复条件。Kafka 事务的适用范围见消息幂等性。

9. 选型​

需求重点比较
事件流长期保留、多组独立重放Kafka 分区日志与保留策略。
按键维护最新状态Kafka compact 与 tombstone 窗口。
复杂消息路由、逐条任务确认RabbitMQ exchange、queue 与 ack。
短时流量削峰队列容量、消费余量和消息时效。

Kafka 可通过分区、批量和顺序 I/O 扩展吞吐。RabbitMQ 便于表达多种路由与逐条投递控制。选型还需验证客户端、故障恢复和运维成本。

10. 常见问题​

10.1 Kafka 的队列用途​

一个普通消费组可分担 topic 的处理工作。多个组则独立读取相同日志。消息生命周期由保留策略控制。

10.2 削峰容量​

11 · 面试题卡片​

本页题目与参考回答

11.1 Kafka 和 RabbitMQ 的模型有什么区别,应该如何选择​

出现公司:快手

考察重点

  • 分区日志、offset、exchange、queue 与 acknowledgement。
  • 保留重放、路由和顺序边界。
  • 投递语义与外部副作用。

相关内容:Kafka 分区日志至选型。

参考回答

Kafka 保存分区日志,消费组用 offset 管理进度。

记录可在保留范围内重放。RabbitMQ 用 exchange 和 binding 路由到队列,再逐条投递确认。

长期事件流和多个独立消费视图适合比较 Kafka。复杂路由和任务确认适合比较 RabbitMQ。选择还要考虑保留、顺序和恢复条件。外部业务副作用需独立设计幂等。

11.2 Kafka 消费后还能一直重放吗,compact 保留全部历史吗?​

出现公司:暂无已核验的公开来源(本站自测)

考察重点:保留窗口、键状态与 offset 空洞。

相关内容:保留与日志压缩。

参考回答

重放范围受日志保留和清理策略约束。

delete 可删除过期 segment,即使消费者尚未读取。compact 清理同键旧记录,保留最新状态所需的数据。原 offset 保持不变,因此日志中会出现空洞。

12. 参考资料​