连载中 4/20

核心模型:消息怎么从生产者走到消费者

2026-07-30 · 2473 阅读 · 0 评论 · 0 赞

地基篇:概念不牢,地动山摇

选型定了 RocketMQ,老王摩拳擦掌要写代码,被同组的资深工程师拦住了:先把几个核心概念吃透,不然后面配置一堆参数,你连每个参数在影响旅程的哪一段都分不清。这一篇就是那块地基。

全景:一条消息的完整旅程

先把地图画出来,整条链路是:

生产者 --发送--> Broker(Topic -> Queue 存储) <--拉取/推送-- 消费者组(组内多个消费者)
                     |
                 消费进度 offset 也记在这里

下面逐段拆开。

Topic:消息的逻辑分类

Topic 是消息的「栏目」。老王定义了三个主题:ORDER_PAID(订单已支付)、ORDER_TIMEOUT(订单超时)、STOCK_CHANGED(库存变更)。生产者发消息时指定 Topic,消费者订阅 Topic,双方只认栏目不认人——这就是解耦在物理上的落点。

实践上有条经验:Topic 按业务事件划分,而不是按接收方划分。「订单已支付」是一个事件,积分、优惠券、短信三个团队都来订阅它;而不是反过来给每个团队建一个 Topic,把一条消息复制发三遍。

Queue:Topic 的物理分片

Topic 是逻辑概念,真正存消息的是队列——RocketMQ 叫 MessageQueue,Kafka 叫 Partition,叫法不同,本质一样:把一个 Topic 的消息水平切到多个队列里,并行能力就来自这里

发消息时决定进哪个队列,常见两种路由方式:轮询(均匀分摊,吞吐最优)和按 key 哈希(同一个订单号永远进同一条队列——这是顺序消息的基础,第 8 篇细讲)。队列数量决定了消费并行度的天花板:8 个队列最多 8 个消费者同时干活,第 9 个只能围观。所以建 Topic 时队列数要按峰值消费量预留。

消费者组:并行与广播的开关

消费者组(Consumer Group)是 MQ 里最精妙的设计,两条规则:

  • 组内独占:同一个组里的消费者分摊队列,一条消息只被组内一个消费者消费——这是负载均衡;
  • 组间广播:不同组各自独立,都能拿到全量消息——积分服务一个组、短信服务一个组,互不干扰。

扩容加机器就是往组里加消费者,队列自动重新分配(分配的规则变化就是 Kafka 里著名的 Rebalance,第 14 篇专门讲它的风暴问题)。想回放历史消息?新起一个组名从头消费即可——消费进度是按组记录的,这是消息可回溯的基础。

推还是拉:一个经典的折中

消息到了 Broker,怎么交给消费者?两条路:

推模式:Broker 主动推给消费者,消息一到就送达,延迟极低。但风险是不知道消费者的饭量——推得太猛,慢消费者内存爆仓。RabbitMQ 用 prefetch(预取上限)做流控,本质是给推加了个刹车。

拉模式:消费者按自己的节奏来拉,永远不会被撑到。但纯拉有个致命伤:没有消息时空轮询,既浪费 CPU 又让延迟变高。

工业界的答案是长轮询(Long Polling):消费者发起拉取请求,Broker 没有消息时不立刻返回空,而是挂住请求等一小会儿,期间有消息就立刻返回。Kafka 的 poll 和 RocketMQ 的拉取都是这个思路——拉模式的自主权加上推模式的低延迟,两头都要。

offset:消费进度的小本本

每个队列的每条消息有个序号(Kafka 叫 offset,RocketMQ 叫消费位点),消费者组每消费一条,进度就往前挪一格,这个小本本记在 Broker 端。消费者重启,读一下小本本,从上次的地方接着干,不会重头再来。

小本本什么时候写,藏着一个大坑:先提交位移再处理业务,崩溃时会丢消息;先处理再提交,崩溃时会重复消费。这是「不丢」与「不重」的根本矛盾来源,第 5-7 篇的所有机制都围着这个矛盾转。

小结

一张图记住核心模型:Topic 管分类,Queue 管并行,消费者组管分摊与广播,长轮询管效率,offset 管进度。队列数定并行天花板,组名定回溯能力,位点提交时机定丢与重的天平

地基打完,开始盖楼。下一篇进入本系列最核心的主题:消息不丢(上)——生产端怎么保证消息真的送到了 Broker。从同步发送到发送重试,再到本地消息表,三层防线逐个上。

503

10 年全栈工程师 · 503咖啡馆主理人

#消息队列#MQ#Topic#消费者组#推拉模式

评论 (0)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 3 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞