资讯动态

一条MQTT消息在EMQX内部怎么流转:订阅树、主题匹配、会话队列(架构视角)

发布时间:2026/10/23 2:55:57 来源:尧图企业网站定制
一条MQTT消息在EMQX内部怎么流转订阅树、主题匹配、会话队列架构视角前面几篇我们都在Broker 外面看 MQTT。这一篇钻进去一条 PUBLISH 消息从设备发出来在 EMQX 内部到底经历了哪些关卡才最终到达每一个订阅者看懂这条链路你就不再是会配会用的使用者而是能定位问题在哪个环节的架构者。本文以 EMQX 5.x 的分层架构为例思路对其它 BrokerMosquitto、HiveMQ同样适用。一、先看 EMQX 的分层架构EMQX 在设计上把职责分成清晰的几层每层专注一件事接入设备1连接层 Connection Layer管理 TCP 连接、收发字节流设备2会话层 Session Layer每个客户端一个会话订阅关系、inflight 消息、离线队列路由层 Route Layer订阅树 Topic Trie 路由表做主题匹配分布式层 Distributed Layer集群路由、跨节点转发会话/队列存储路由表emqx_route / emqx_route_filters记住这四层的分工整条链路就清晰了连接层只负责把字节收进来、把字节发出去不关心消息内容。会话层为每个客户端维护一个会话——它订阅了什么、哪些 QoS1/2 消息在等确认、离线时有哪些消息在排队对应第 8 篇的会话保持。路由层核心是订阅树Topic Trie和路由表负责回答这条消息该给谁。分布式层集群模式下决定该给哪个节点上的谁。二、路由的核心订阅树Topic Trie路由层是整条链路的大脑。它维护着一棵订阅树把每个客户端订阅的过滤器都挂到对应的节点上。举个例子假设有四个客户端分别订阅客户端 A 订阅t//x 客户端 B 订阅t//y 客户端 C 订阅t/# 客户端 D 订阅t/a订阅树长这样(root) └── t ├── ── x → [A] 通配一个层级 ├── ── y → [B] ├── a → [D] 精确匹配 └── # → [C] # 通配所有剩余层级关键理解这棵树的节点既存精确的主题段也存、#这样的通配段。消息来了就在树上做一次匹配遍历——这就是为什么第 4 篇说通配订阅会影响匹配性能通配节点越多一次发布要检查的分支就越多。三、一条消息的完整旅程把发布和投递串起来一条t/a/x的 PUBLISH 是这样走的订阅者D(t/a)订阅者C(t/订阅者A(t//x)路由层会话层连接层设备发布者订阅者D(t/a)订阅者C(t/订阅者A(t//x)路由层会话层连接层设备发布者命中t/a → Dt//x → At/PUBLISH topict/a/x, QoS1解析报文交给会话层处理 QoS1 确认、更新 inflight问t/a/x 该发给谁遍历订阅树匹配返回匹配的订阅者列表 [A, C, D]投递入 A 的会话队列 → 按 QoS 发出投递投递拆解成五步收包解析连接层收到字节流按第 6 篇讲的固定头规则解析出这是一条 PUBLISH主题t/a/xQoS1。会话处理会话层先处理这条消息对发布者自己的语义——QoS1 要先回 PUBACK、记录 inflight 状态QoS2 则要走四拍握手。路由匹配把主题t/a/x交给路由层在订阅树上找出所有匹配的订阅者。本例命中三条精确的t/aD、通配的t//xA、多层的t/#C。投递对每个命中的订阅者把消息塞进它的会话队列再按订阅时的 QoS还记得第 3 篇说的min(发布 QoS, 订阅 QoS)吗发送。附加动作如果这条 PUBLISH 带RETAIN1还要更新保留消息索引第 8 篇的机制如果命中的订阅在别的节点则交给分布式层转发。四、离线与队列消息去哪排队了如果某个订阅者比如 D此刻不在线会怎样这取决于它的会话类型在线离线干净会话持久会话路由层匹配到 DD 在线吗直接投递会话类型丢弃QoS0 也一样丢入 D 的离线队列等 D 重连后补投递持久会话 QoS1/2消息进离线队列等客户端重连同一个 Client ID后补投递。干净会话 或 QoS0消息直接丢弃。离线队列会占用 Broker 内存——队列深度没设上限时海量离线消息就是积压事故的温床这是第 12 篇故障复盘的根因。五、集群模式跨节点的消息怎么路由单机版理解透了集群版只是加了一层这张订阅表分布在哪的问题。EMQX 集群用全局路由表记录哪个主题/过滤器在哪个节点上有订阅者全局路由表Node1本地订阅者直接投递跨节点转发跨节点转发发布者 → Node1t/a → Node1, Node3t/# → Node2Node1 订阅者Node2 订阅者Node3 订阅者精确主题用路由表直接查目标节点通配主题用独立的通配索引emqx_route_filters做匹配路由信息在集群里复制同步节点宕机时会清理过期路由。对使用者而言集群路由是透明的——你往任意节点发布Broker 自己会把消息送到正确节点上的订阅者。这也是 EMQX 能水平扩展、扛百万连接第 15 篇会讲的架构基础。六、 可拿走资产消息流转架构图Broker 内部PUBLISHRETAIN1跨节点发布者EMQX Broker连接层收包解析会话层QoS确认/状态路由层订阅树匹配会话队列按订阅QoS投递保留消息索引分布式层集群路由订阅者1订阅者2订阅者N排查视角速查哪类问题查哪一层症状重点排查层思路连接建立失败连接层端口、TLS、认证消息丢失会话层QoS、会话类型、订阅 QoS消息没发给预期的人路由层主题/过滤器是否匹配、通配符离线消息堆积会话层队列队列深度、持久会话集群下消息不到分布式层路由表、节点状态七、写在最后恭喜你到这一篇为止你已经把 MQTT 从概念 → 部署 → QoS → 主题 → 报文 → 特性 → 机制 → 扩容 → Broker 内核完整走了一遍。L2 深度层到此收官。但从下一篇开始我们进入这个系列最值钱的部分——L3 护城河层真实生产事故复盘。第一篇我讲的是一次把我半夜叫起来的故障设备疯狂重连把 Broker 直接打挂。我会还原完整的时间线、排查弯路再给你一份指数退避参数模板。这是全网少见的甲方真实经历。 评论区提问你有没有好奇过消息明明发了为什么订阅者收不到结合今天讲的四层架构你遇到过的问题大概卡在哪一层欢迎留言一起定位。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑