欢迎光临
我们一直在努力

【第二章08】MQTT主题详解

MQTT主题是MQTT协议中实现消息路由的核心机制,作为发布者与订阅者之间约定的消息通道,支撑起整个物联网系统的消息流转,以下是完整详解:
在这里插入图片描述

自定义主题

一、核心基础定义

MQTT主题是基于UTF-8编码的字符串,采用类似URL的分层结构(如sensor/room1/temperature),它是消息传递的寻址通道,也是业务逻辑在通信层面的映射。发布者向特定主题发送数据,代理服务器(Broker)会依据订阅者的需求完成精准路由。

二、三个关键概念区分

‌Topic Name(主题名)‌:发布消息时使用的确定字符串,严禁包含通配符,是标识特定消息的唯一通道,示例:sensor/room1/temperature。
‌Topic Filter(主题过滤器)‌:订阅消息时使用的字符串,可使用通配符也可做精确匹配,本质是一个“匹配模板”,示例:sensor/+/temperature。
‌Topic(主题)‌:Broker内部将Topic Name与Topic Filter匹配成功后形成的逻辑通道,MQTT版消息队列中无需预先创建主题,发布或订阅时会自动生成。

三、通配符使用规则

通配符仅能用于订阅场景,不可用于发布,MQTT支持两类标准通配符:
‌单层通配符+‌:必须占据一个完整层级,匹配该层级的任意字符串,例如订阅sensor/+/temperature,可匹配sensor/bedroom/temperature,但无法跨多层匹配。
‌多层通配符#‌:必须放在主题过滤器的末尾且前面加斜杠,可匹配零个或多个任意层级,例如订阅sensor/bedroom/#,可覆盖该节点下所有子层级的消息。
四、使用最佳实践
采用“场景/设备类型/数据类型/位置”的分层命名规范,便于大规模物联网系统的消息分类与权限管控。
避免使用特殊字符,控制单主题长度在合理范围,减少Broker的路由匹配开销;高吞吐量场景下避免使用范围过广的多层通配符订阅,防止接收大量无关消息增加负载。

系统主题

一、定义

MQTT系统主题是MQTT Broker(消息代理)‌内置预留的特殊主题‌,以$SYS/为固定前缀,不属于用户自定义的普通业务主题,用于代理对外暴露自身运行状态、统计数据等系统级信息。

二、核心作用

它是监控MQTT集群运行的核心通道,订阅者可通过订阅对应系统主题,实时获取代理的在线客户端数、消息收发总量、连接状态、会话留存数等运维关键指标,无需额外开发监控接口。

三、命名规则

所有系统主题必须以SYS/作为固定起始前缀,后续层级由Broker厂商自定义,无统一强制标准。系统主题不支持普通主题的通配符全量匹配,直接订阅SYS/作为固定起始前缀,后续层级由Broker厂商自定义,无统一强制标准。
系统主题不支持普通主题的通配符全量匹配,直接订阅
SYS/作为固定起始前缀,后续层级由Broker厂商自定义,无统一强制标准。系统主题不支持普通主题的通配符全量匹配,直接订阅
SYS/#才能获取所有系统主题消息,普通的#通配符无法匹配到以$开头的系统主题。

四、使用注意事项

系统主题的推送频率由Broker配置控制,默认不会高频推送,避免占用过多带宽。
生产环境需严格限制系统主题的订阅权限,防止未授权用户获取集群核心运行数据,引发安全风险。
不同厂商的MQTT Broker(如EMQX、Mosquitto)的系统主题层级命名存在差异,需参考对应产品的官方文档使用。

五、配置客户端权限:{allow, all, subscribe, [“$SYS/#”, “#”]}.

主题说明
$SYS/brokers 集群节点列表
SYS/brokers/SYS/brokers/SYS/brokers/{node}/version EMQX 版本
SYS/brokers/SYS/brokers/SYS/brokers/{node}/uptime EMQX 运行时间
SYS/brokers/SYS/brokers/SYS/brokers/{node}/datetime EMQX 系统时间
SYS/brokers/SYS/brokers/SYS/brokers/{node}/sysdescr EMQX 系统信息

如果定义系统主题报错:可能是客户端权限问题
检查是否配置允许订阅系统主题
在这里插入图片描述

这条配置语句 {allow, all, subscribe, [“$SYS/#”, “#”]}. 是 ‌EMQX‌(一款流行的开源 MQTT 消息服务器)中访问控制列表(ACL)的一条规则。

它的核心含义是:‌允许所有客户端订阅所有主题,包括以 $SYS/ 开头的系统主题。‌

以下是详细解读:

  • 语法拆解
    ‌allow‌: 动作类型,表示“允许”该操作。与之相对的是 deny(拒绝)。
    ‌all‌: 适用对象,表示该规则适用于‌所有‌连接到 Broker 的 MQTT 客户端(无论用户名、ClientID 或 IP 地址如何)。
    ‌subscribe‌: 操作类型,表示该规则仅针对‌订阅‌行为生效。它不限制发布(publish)或其他操作。
    ‌[“$SYS/#”, “#”]‌: 主题过滤器列表。
    “#”: MQTT 标准通配符,匹配所有非系统主题(即不以 $ 开头的主题)。
    “$SYS/#”: 专门匹配所有以 $SYS/ 开头的系统主题。
  • 为什么需要这样配置?
    在 MQTT 协议标准及 EMQX 的默认安全策略中,‌以 $ 开头的主题(如 $SYS/…)具有特殊性‌:
  • ‌默认隔离‌:普通的通配符订阅 # ‌不会‌匹配到以 $ 开头的主题。这是为了防止普通业务客户端意外接收到大量的系统监控数据,同时也出于安全考虑,防止未授权用户获取服务器内部状态。
    ‌显式授权‌:如果希望某个客户端能够监控系统状态(如在线人数、消息吞吐量、客户端上下线事件等),必须‌显式地‌在 ACL 中授权其订阅 $SYS/#。
    因此,这条规则的作用是‌打破默认隔离‌,赋予所有客户端完整的订阅权限,既包括业务数据,也包括系统监控数据。

  • 潜在风险与建议
    ‌安全风险‌:允许 all 客户端订阅 $SYS/# 意味着任何连接到你服务器的设备或程序都可以获取服务器的详细运行状态(如版本、 uptime、负载、客户端列表等)。在生产环境中,这通常被视为‌不安全‌的配置,因为它泄露了系统内部信息。
    ‌性能影响‌:如果大量客户端同时订阅 $SYS/# 并接收高频的系统状态推送(如每秒更新的统计信息),可能会增加 Broker 的网络带宽压力和客户端的处理负担。
    ‌最佳实践建议:‌
  • ‌最小权限原则‌:不要对 all 用户开放 $SYS/# 订阅权限。
    ‌按需授权‌:仅允许特定的监控账号或管理后台订阅 KaTeX parse error: Expected 'EOF', got '#' at position 5: SYS/#̲。例如:
    erlang
    {al…
    SYS/#“]}.
    {allow, all, subscribe, [”#"]}. % 普通用户只能订阅业务主题
    ‌区分读写‌:通常只授予监控账号“订阅”权限,严禁授予“发布”权限到 $SYS/ 主题,以防恶意篡改系统状态。
    总结
    这条 ACL 规则是一个‌宽松且高风险‌的配置,常用于开发测试环境以便快速调试和监控。在生产环境中,应改为更精细化的权限控制,仅允许受信任的管理员客户端订阅系统主题。

    六、客户端上下线事件

    在EMQX中,客户端上下线事件是核心的运维与业务集成能力,可通过系统主题、规则引擎等多种方式完整捕获,具体说明如下:

    一、核心事件主题
    EMQX默认开启上下线事件通知,通过$SYS/开头的系统主题发布事件,主题格式与节点名称绑定:

    客户端上线事件:SYS/brokers/SYS/brokers/SYS/brokers/{node}/clients/${clientId}/connected
    在这里插入图片描述
    客户端上线
    在这里插入图片描述

    客户端下线事件:SYS/brokers/SYS/brokers/SYS/brokers/{node}/clients/${clientId}/disconnected
    在这里插入图片描述
    在这里插入图片描述

    如果不想逐个订阅单客户端的事件,可直接使用通配符一次性订阅所有上下线事件:$SYS/brokers/+/clients/#。

    二、事件Payload格式
    上线事件的JSON消息体包含客户端连接的完整信息,示例结构:

    {
    "username": "undefined",
    "ts": 1785395719963,
    "sockport": 1883,
    "protocol": "mqtt",
    "proto_ver": 5,
    "proto_name": "MQTT",
    "keepalive": 60,
    "ipaddress": "127.0.0.1",
    "expiry_interval": 0,
    "connected_at": 1785395719963,
    "clientid": "mqttx_69fb37b8",
    "clean_start": true
    }

    下线事件额外包含断开原因字段,可区分正常主动断开、网络异常断开等场景,示例结构:

    {
    "username": "undefined",
    "ts": 1785395771382,
    "sockport": 1883,
    "reason": "normal",
    "protocol": "mqtt",
    "proto_ver": 5,
    "proto_name": "MQTT",
    "ipaddress": "127.0.0.1",
    "disconnected_at": 1785395771382,
    "connected_at": 1785395719963,
    "clientid": "mqttx_69fb37b8"
    }

    三、与LWT遗言机制的区别
    普通MQTT的LWT遗言机制仅能捕获客户端异常离线的通知,无法感知客户端主动调用disconnect的正常断开行为;而EMQX的上下线系统主题可以完整覆盖所有场景,无论是正常主动断开、网络异常中断,都能准确推送通知。

    四、生产环境最佳实践
    ‌权限配置‌:默认ACL规则会拒绝普通客户端订阅KaTeX parse error: Expected 'EOF', got '#' at position 5: SYS/#̲,需要在ACL配置中单独给运维…SYS/#的订阅权限,避免全量开放带来的安全风险。
    ‌业务集成推荐‌:如果是面向业务系统的事件消费,更推荐使用EMQX规则引擎的events/client/connected、events/client/connected、events/client/connectedevents/client/disconnected事件主题,这类主题不与节点名称绑定,稳定性更高,还可以在规则中直接完成数据过滤、脱敏,再转发到自定义的业务主题,无需客户端自行处理原始系统主题数据。

    赞(0)
    未经允许不得转载:171主机测评 » 【第二章08】MQTT主题详解
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址