← Writing

消息队列复习

31-05-2026

关于消息队列,kafka 架构

资料来源

  • 小林

  • gpt

  • <<深入理解 kafka>>


消息队列101

功能

  • 异步:解耦服务依赖。例子:发短信/ 用餐后写评价
  • 削峰:解决瞬时流量过高,单一服务可能扛不住的场景。例子:抢票
  • 分发:多服务依赖同一状态变化,由上游通知下游变成下游订阅上游。例子:下单

Kafka

架构

  • 生产者:producer
  • 服务节点:broker
    • 主题:topic【逻辑概念】
    • 分区:partition【物理实现】
  • 消费者:consumer
    • 消费者组:逻辑概念

关系图:producer、broker、topic、partition

Rendering diagram...

记忆方式:

  • producer 面向 topic 发消息,不需要直接关心消息最终落在哪台 broker 上
  • topic 是逻辑名,用来表达一类消息,比如订单事件、支付事件
  • partition 是 topic 的物理拆分,每个 partition 都是一份可追加的日志文件
  • broker 是服务节点,真正存放 partition 数据;一个 topic 的多个 partition 可以分布在多个 broker 上

架构理解

  • broker 是一个独立服务端进程,topic 是逻辑概念,一个 broker 可以有多个 partition
  • partition 是物理实现,通过 offset 来唯一定位消息,是个可追加的日志文件
  • topic 是逻辑概念:topic 可以包括多个 broker 的多个分区

功能理解

  • 通过 partition:实现 topic 的水平扩展【同一个消费者组内,一个 partition 同一时刻只会分配给一个 consumer;一个 consumer 可以消费多个 partition】

  • 消费者组:引入消费者组,可以扩展消费能力,而不用自定义代码逻辑

关系图:consumer、consumer group

Rendering diagram...

消费者组记忆方式:

  • 图里的实线表示 Consumer Group A 内部的分摊消费;虚线表示 Consumer Group B 独立消费同一批 partition
  • 同一个 consumer group 内:多个 consumer 是合作关系,大家一起分摊 topic 的 partition
  • 同一个 consumer group 内:一个 partition 同一时刻只会被一个 consumer 消费,避免同组重复消费
  • 一个 consumer 可以消费多个 partition;如果 consumer 数量超过 partition 数量,多出来的 consumer 会空闲
  • 不同 consumer group 彼此独立,各自维护 offset;同一条消息可以被不同 group 都消费一次

系统设计

延时队列

死信队列

优先级队列

这几个在 rocketmq 都支持,但是 kafka 不支持,所以要大概了解下设计思路和实现

延时队列

  • 设计思路:先把延时消息放到一个地方,然后启动服务轮询,如果符合要求,再放到对应消费的 mq 里面供销费
    • 延时消息放到 redis/mysql 中 【设计好数据库表 timestamp, biz_id, msg_content, key, status..】
    • 启动服务进行轮询:定期轮询 mysql/redis 扫 status =0 & timestamp < 当前时间的 把这些记录拿出来
    • 找到合适的记录,拼接成 msg 放到 mq 中
  • 拓展
    • 消息存储时间分长短:时间轮 & db/reids
    • db 设计

优先级队列

  • 设计思路:分成 2-3 个队列拆解,不同的队列就是不同的优先级,然后让消费者去不同的队列里面拿任务
    • 分成多个 mq:1st_mq, 2nd_mq, 3rd_mq
    • 不同的消费者/消费者组 去不同的 mq 里面拿消息消费
  • 拓展
    • 权重思路:防止有些消费者一直拉不到消息,比如可以按权重加权,确保低优先级的最好也能被消费到

死信队列:异常情况的队列【生产端/消费端】

  • 设计思路:设计一个 topic,然后让业务端异常的时候把 message 放到一个特殊的队列中
  • 拓展
    • message 设计:retry_cnt,fail_reason, 错误堆栈信息等等