**MQTT Broker 是一种服务端程序:它接收 MQTT 发布客户端发送的消息,根据消息 Topic 匹配订阅,并把消息投递给订阅客户端。**发布者与订阅者不需要彼此直连;它们分别连接 Broker,而且同一个客户端既可以发布,也可以订阅。
Broker 是 MQTT 发布—订阅模型的路由中心。根据协议版本、连接参数和 Broker 策略,它还会认证客户端、执行 Topic 权限、维护订阅与会话状态、处理服务质量(QoS)投递、保存 Retained Message,并在客户端异常断开时发送遗嘱消息。这些行为由 OASIS MQTT 5.0 标准定义;存储、扩缩容、可观测性与可用性则属于具体实现和服务能力,并非协议本身的保证。
MQTT Broker 如何工作?
- 发布者与一个或多个订阅者分别和 Broker 建立 MQTT 连接。Broker 接受或拒绝连接,并可对客户端进行身份认证。
- 订阅者发送
SUBSCRIBE报文,其中包含factory/+/temperature这样的 Topic Filter。Broker 将订阅记录在客户端的当前会话或持久会话中。 - 发布者发送带有 Topic Name、载荷和 QoS 等级的
PUBLISH报文;它不会直接指定某个订阅者。 - Broker 将 Topic Name 与有效的 Topic Filter 比较,再按照每次投递适用的 QoS 规则,把消息转发给所有匹配的订阅。
- 如果配置允许会话状态在断开后继续存在,Broker 可以保留订阅,并为之后重连的客户端排队符合条件的 QoS 1 或 QoS 2 消息。MQTT 3.1.1 与 MQTT 5 的会话语义不同,需要明确配置。
例如,传感器可以向 factory/line-1/temperature 发布消息,仪表盘则订阅 factory/+/temperature。匹配与投递由 Broker 完成,两个客户端都不需要知道对方的地址。可以跟随 MQTT 教程完成一套可直接执行的连接、发布和订阅流程,或用合成数据在仅供测试的公共 MQTT Broker做一次性连通性检查。
区分 MQTT 协议、Broker、Client 与托管 Broker
这些术语对应系统中的不同部分:
| 术语 | 它是什么 | 它不是什么 |
|---|---|---|
| MQTT 协议 | 规定连接、发布、订阅、确认、会话与断开的线级通信规则。 | 服务端程序或托管产品。 |
| MQTT Broker | 接受 MQTT 客户端连接,并把发布消息路由到匹配订阅的服务端软件。 | MQTT 标准本身,也不是设备 SDK。 |
| MQTT Client | 使用 MQTT 客户端库建立连接的设备或应用;它可以发布、订阅,或同时承担两种角色。 | 不一定是终端设备,后端服务也可以是 Client。 |
| 托管 MQTT Broker | 由服务商负责运行,并提供托管、升级、监控、扩缩容、备份与运维支持的 Broker 服务。 | 一种不同的消息协议。 |
如果要理解线级行为,请继续阅读本文和 MQTT QoS 指南;生产环境的威胁边界见 MQTT 安全指南。如果正在选择由谁运行服务端,可比较自建与托管 MQTT Broker。RunMQTT 首页承接托管云 MQTT Broker 产品需求,本文则专注协议与 Broker 概念。
从 Broker 基础进入 MQTT 5 迁移
MQTT 3.1.1 仍然足以支撑许多设备群。当应用为了会话生命周期、陈旧指令、错误诊断、请求响应关联或消费者协作维护了大量自定义逻辑时,迁移到 MQTT 5 才会产生明确价值。
这不是一次必须同时完成的协议切换。Broker 通常可以同时服务 MQTT 3.1.1 与 MQTT 5 客户端,但每条客户端连接只会协商一个版本。更安全的方法是在保持载荷和主题契约兼容的前提下,每次只迁移一类客户端和一项能力。
从迁移理由开始,而不是从版本号开始
先把 MQTT 5 能力对应到已经观察到的问题:
| 运维问题 | 值得评估的 MQTT 5 能力 |
|---|---|
| 离线会话保留时间过长 | Session Expiry Interval |
| 设备重连后收到陈旧指令 | Message Expiry Interval |
| 不同连接失败看起来完全相同 | 原因码与原因字符串 |
| 客户端不知道 Broker 的实际限制 | CONNACK 返回的服务端限制 |
| 请求响应依赖自定义载荷字段 | Response Topic 与 Correlation Data |
| 小载荷中,长主题名占据主要流量 | Topic Alias |
| 多个消费者需要有边界的水平分流 | Shared Subscription |
不要只为了“已经使用 MQTT 5”而迁移。只采用少量经过测试且真正解决问题的能力,比启用应用无法观察和处理的属性更安全。
盘点完整兼容路径
记录每个 Broker 端点、设备 SDK、网关、后端消费者、代理和测试工具的协议支持情况。不要只相信“支持 MQTT 5”的标签,还要验证实际行为:
- 客户端能够发送哪些属性,哪些属性可以暴露给应用代码;
- 重连后是否保持配置的会话语义;
- Broker 返回的限制是否会被客户端真正执行;
- 日志和指标如何暴露原因码;
- MQTT 5 客户端发布消息后,MQTT 3.1.1 订阅者会收到什么。
混合版本期间,主题和载荷必须能被两个版本共同理解。如果旧消费者仍然依赖某个载荷字段,就不能只把它移动到 MQTT 5 属性中。
分开 Clean Start 与会话生命周期
MQTT 3.1.1 的 Clean Session 同时控制两件事:连接时是否丢弃旧会话,以及断开后是否保留会话状态。MQTT 5 使用 Clean Start 与 Session Expiry Interval 将两者分开。
迁移时需要明确每类客户端的目标生命周期:
| 客户端类型 | Clean Start | 会话过期 | 目标 |
|---|---|---|---|
| 无状态发布者 | true | 0 | 永不保留会话状态 |
| 间歇连接设备 | 首次连接后通常为 false | 有边界的时间 | 短期恢复订阅或排队 QoS 消息 |
| 后端 Worker | 取决于订阅初始化方式 | 短且明确 | 进程重启后恢复,但不无限保留 |
必须验证 Session Present 响应。客户端需要据此判断是否重新订阅,不能假设 Broker 一定保存了状态。
让失去价值的消息自动过期
Message Expiry Interval 允许发布者声明消息还可以保留多久。它特别适合指令、临时配置,以及在故障后不应阻塞当前状态的高频遥测。
消息过期不能替代应用校验。指令载荷仍应包含操作 ID、签发时间和业务截止时间,设备端也要拒绝过期或已经执行的工作。Broker 可以减少一部分迟到投递,但接收端才是最后的安全边界。
把原因码与服务端限制变成运维数据
MQTT 5 为确认报文增加了更细的原因码,也允许服务端声明 Maximum Packet Size、Receive Maximum、Maximum QoS、Retain Available 和 Shared Subscription Available 等约束。
不要再把所有问题折叠成“连接断开”。指标应按稳定的原因码分组,日志可以附带有边界的客户端类型和操作信息,但不能记录原始凭据或无限增长的主题值。
当服务端限制低于客户端配置时,客户端也必须有确定行为:减少在途窗口、在发布前拒绝过大载荷,或者让部署检查失败。静默忽略协商结果会制造难以复现的生产问题。
谨慎替换自定义请求响应约定
Response Topic 与 Correlation Data 可以表达请求响应关系,不需要每种载荷都重新设计关联字段。请求方发布响应目标和不透明的关联值,响应方在结果中原样返回该值。
权限边界仍然存在。设备不能任意选择响应主题,后端服务也不应订阅没有边界的回复命名空间。超时、幂等和指令过期仍然属于应用责任。
User Properties 适合携带少量路由或链路追踪元数据。但当消息还会进入数据库、MQTT 3.1.1 消费者或非 MQTT 系统时,载荷仍应是持久的业务契约。
采用 Topic Alias 前先测量收益
建立映射后,Topic Alias 可以用当前连接范围内的整数替代重复主题名。当载荷很小而主题很长时,它可能显著降低开销。
映射不会跨重连保留,两个方向的上限也分别协商。应把它视为传输优化,而不是主题模型变更。先在有代表性的设备上测量流量与 CPU 收益,再决定是否接受额外客户端状态复杂度。
每次只迁移一类客户端
一套可控的迁移顺序是:
- 先让非关键后端消费者启用 MQTT 5;
- 采集原因码和服务端限制,但暂不改变业务行为;
- 在一组金丝雀主题上增加单项能力,例如消息过期;
- 测试重连、Broker 重启、发布拒绝和混合版本投递;
- 扩展到一批网关或设备;
- 在新行为可被生产环境观测前,保留回退到 MQTT 3.1.1 的能力。
一次成功发布不能证明整个设备群兼容。还要演练 QoS 确认、Retained Message、Last Will、会话恢复、授权失败、超大报文和离线队列。
MQTT 5 迁移退出清单
将 MQTT 5 设为默认版本前,确认:
- 每类客户端都有明确的协议版本与回退策略;
- 会话状态具有经过测试的有限生命周期;
- 时效性消息同时在 Broker 与应用边界过期;
- 原因码能够进入仪表盘与 Runbook;
- 客户端会执行服务端声明的限制;
- MQTT 3.1.1 消费者仍能收到所有必要业务字段;
- 回退不会遗留无法恢复的会话、订阅或排队指令。
MQTT Broker 常见问题
MQTT 必须使用 Broker 吗?
必须。MQTT 采用客户端—服务端架构,客户端需要连接 Broker,由 Broker 接收发布消息并分发给匹配的订阅。设备间应用可以把 Broker 运行在其中一台设备或网关上,但该进程仍然是 MQTT Broker;标准 MQTT 客户端不会绕过它彼此直接发布消息。
MQTT Broker 会存储每一条消息吗?
不会。普通投递由匹配订阅和会话状态决定。只有发布者将消息标记为 Retained Message 时,Broker 才会按保留消息语义存储它;对于断开但拥有持久会话的客户端,Broker 也可能排队符合条件的 QoS 1 或 QoS 2 消息。具体上限、过期与持久化行为取决于 MQTT 参数和 Broker 实现。
应该自建还是使用托管 MQTT Broker?
自建让团队直接控制基础设施和 Broker 配置,但升级、扩缩容、监控、备份、故障响应与安全加固也由团队负责。托管 Broker 会把其中许多运维工作交给服务商。评估时应比较工作负载隔离、合规、可用性目标、团队运维能力与总成本,而不能只看协议兼容性。
MQTT Broker 与 MQTT Server 有什么区别?
在 MQTT 文档中,“Server”是协议角色,“Broker”则是产品与架构中对该角色的常用称呼。两者都指接受客户端连接并路由应用消息的组件;“托管 Broker”还说明了由谁运维,以及周围包含哪些服务能力。
规范细节应以 OASIS MQTT 5.0 标准为准。MQTT QoS 实验解释投递握手,MQTT 主题设计指南则覆盖迁移期间应保持稳定的授权契约。
