三向解耦
MQTT 是客户端、代理、客户端组成的三方结构:发布者把消息发到某个主题,订阅者提前声明关心哪些主题,由代理完成匹配与转发。这样换来三种解耦——空间上双方不需要知道对方地址,时间上不需要同时在线,同步上发布者发完即可继续、不必等待处理结果。代价是代理成为必须高可用的中间节点。
基本信息
| 角色划分 | 发布者、订阅者、客户端、代理(服务端) |
|---|---|
| 寻址方式 | 主题,按斜杠分层的 UTF-8 字符串 |
| 消息语义 | 一对多、多对多,一条消息可被多个订阅者收到 |
| 连接方式 | TCP 长连接,也可承载于 TLS 或 WebSocket 之上 |
| 与请求响应的差别 | 默认没有响应语义,需要时用响应主题与关联数据自行实现 |
与其他模型对照
| 维度 | 发布订阅 | 请求响应 |
|---|---|---|
| 耦合度 | 发布者不知道订阅者是谁、有几个 | 调用方必须知道服务地址与接口 |
| 在线要求 | 双方可异步在线,代理可缓存会话 | 请求时双方必须同时可用 |
| 扩展方式 | 增加订阅者不影响发布者 | 增加消费者需要服务发现与负载均衡 |
| 故障影响 | 代理不可用则全链路中断 | 单个服务不可用只影响其调用方 |
| 实时性 | 代理转发即可送达,天然适合推送 | 依赖轮询或长连接升级 |
典型使用场景
- 设备遥测上云:大量设备向各自主题发布数据,平台按通配符订阅汇聚
- 指令下发:平台向设备指令主题发布,设备只需订阅自己的主题
- 多消费者共享数据:监控大屏、告警引擎、存储服务同时订阅,互不影响
- 弱网与移动网络:长连接加心跳,避免反复建连的开销
代理是单点,生产环境需要按连接数、吞吐与可用性要求做集群或桥接。不同集群实现对持久会话、共享订阅的支持程度差别很大,选型前要确认。
发布订阅默认没有端到端确认:发布者无法判断设备是否真的收到并执行。关键指令要结合应答主题或平台侧状态回执一起设计。