乐闻世界logo
搜索文章和话题

面试题手册

MQTT 的主题通配符有哪些?如何使用?

MQTT 的主题通配符是一种强大的订阅机制,允许客户端订阅一类主题而不是单个主题,提高了订阅的灵活性。主题通配符类型MQTT 提供两种通配符:1. 单级通配符(+)符号:加号(+)作用:匹配主题中的单个层级位置:可以出现在主题的任何位置限制:不能匹配空层级2. 多级通配符(#)符号:井号(#)作用:匹配主题中的多个层级(包括零个)位置:必须出现在主题的最后限制:必须是主题过滤器的最后一个字符通配符使用示例单级通配符(+)示例订阅主题:home/+/temperature匹配的主题:- home/livingroom/temperature ✓- home/bedroom/temperature ✓- home/kitchen/temperature ✓不匹配的主题:- home/livingroom/kitchen/temperature ✗(层级过多)- home/temperature ✗(层级过少)- home/livingroom/humidity ✗(最后一层不匹配)订阅主题:sensor/+/data/+匹配的主题:- sensor/001/data/temperature ✓- sensor/002/data/humidity ✓- sensor/003/data/pressure ✓不匹配的主题:- sensor/001/data ✗(层级过少)- sensor/001/data/temperature/value ✗(层级过多)多级通配符(#)示例订阅主题:home/#匹配的主题:- home/ ✓- home/livingroom ✓- home/livingroom/temperature ✓- home/livingroom/temperature/value ✓- home/bedroom/humidity ✓不匹配的主题:- home ✗(必须以 / 结尾或包含 /)- office/livingroom ✗(第一层不匹配)订阅主题:sensor/+/#匹配的主题:- sensor/001/ ✓- sensor/001/data ✓- sensor/001/data/temperature ✓- sensor/002/data/humidity/value ✓不匹配的主题:- sensor ✗(层级过少)- office/001/data ✗(第一层不匹配)组合使用示例订阅主题:home/+/sensors/#匹配的主题:- home/livingroom/sensors/ ✓- home/livingroom/sensors/temperature ✓- home/livingroom/sensors/temperature/value ✓- home/bedroom/sensors/humidity ✓不匹配的主题:- home/sensors/ ✗(缺少中间层级)- home/livingroom/sensors ✗(# 必须在最后)通配符规则单级通配符(+)规则匹配单个层级:只能匹配一个非空层级可以多次使用:可以在主题过滤器中多次出现可以出现在任何位置:可以在主题的任何层级使用不能跨层级:不能匹配多个层级多级通配符(#)规则匹配多个层级:可以匹配零个或多个层级必须在最后:必须是主题过滤器的最后一个字符只能使用一次:每个主题过滤器中只能使用一次必须跟随 /:如果主题有多个层级,# 前面必须有 /通配符应用场景1. 设备分类监控场景:监控所有温度传感器订阅主题:sensors/+/temperature效果:接收所有设备的温度数据2. 区域监控场景:监控某个区域的所有数据订阅主题:building/floor1/#效果:接收一楼所有设备的数据3. 设备状态监控场景:监控所有设备的在线状态订阅主题:device/+/status效果:接收所有设备的状态更新4. 数据类型订阅场景:订阅所有告警消息订阅主题:alert/#效果:接收所有类型的告警5. 分层订阅场景:订阅特定类型的所有子主题订阅主题:system/metrics/+/#效果:接收所有系统指标的详细数据通配符限制和注意事项1. 发布限制不能发布到通配符主题:通配符只能用于订阅,不能用于发布主题必须明确:发布时必须指定完整的主题路径2. 订阅限制通配符不能用于主题层级内部:如 home/room+/temperature 是无效的# 必须在最后:home/#/temperature 是无效的+ 不能匹配空:home/+/temperature 不能匹配 home//temperature3. 性能考虑通配符订阅会增加 Broker 负担:Broker 需要进行主题匹配避免过度使用通配符:过多的通配符订阅可能影响性能合理设计主题结构:良好的主题设计可以减少通配符使用4. 安全考虑ACL 权限控制:通配符订阅需要相应的权限避免过度授权:通配符订阅可能暴露过多数据最小权限原则:只授予必要的通配符权限代码示例Python (paho-mqtt)import paho.mqtt.client as mqttdef on_connect(client, userdata, flags, rc): print(f"Connected with result code {rc}") # 单级通配符订阅 client.subscribe("sensor/+/temperature") # 多级通配符订阅 client.subscribe("home/bedroom/#") # 组合通配符订阅 client.subscribe("system/+/metrics/#")def on_message(client, userdata, msg): print(f"Received: {msg.topic} - {msg.payload.decode()}")client = mqtt.Client()client.on_connect = on_connectclient.on_message = on_messageclient.connect("broker.example.com", 1883, 60)client.loop_forever()JavaScript (MQTT.js)const mqtt = require('mqtt');const client = mqtt.connect('mqtt://broker.example.com');client.on('connect', () => { console.log('Connected'); // 单级通配符订阅 client.subscribe('sensor/+/temperature'); // 多级通配符订阅 client.subscribe('home/bedroom/#'); // 组合通配符订阅 client.subscribe('system/+/metrics/#');});client.on('message', (topic, message) => { console.log(`Received: ${topic} - ${message.toString()}`);});最佳实践1. 主题设计层级清晰:主题层级应该清晰、有意义避免过深:主题层级不宜过深(建议不超过 5 层)使用分隔符:统一使用 / 作为分隔符命名规范:使用一致的命名规范2. 通配符使用按需使用:只在需要时使用通配符避免过度通配:避免使用过于宽泛的通配符(如 #)组合使用:合理组合单级和多级通配符性能优化:在高性能场景下减少通配符使用3. 订阅管理及时取消订阅:不再需要的订阅应该及时取消避免重复订阅:避免重复订阅相同的主题监控订阅数量:监控订阅数量,避免过多订阅4. 安全管理权限控制:为通配符订阅设置适当的权限最小权限:只授予必要的最小权限定期审查:定期审查通配符订阅权限通配符性能优化1. Broker 优化选择合适的 Broker:选择支持高效通配符匹配的 Broker配置优化:根据实际需求调整 Broker 配置集群部署:大规模场景下使用集群部署2. 订阅优化精确订阅优先:优先使用精确主题订阅减少通配符层级:减少通配符匹配的层级批量订阅:使用批量订阅减少连接开销3. 主题优化主题前缀:使用主题前缀减少匹配范围主题分组:合理分组主题,减少通配符使用避免通配符嵌套:避免复杂的通配符嵌套MQTT 主题通配符是提高订阅灵活性的重要机制,合理使用可以简化应用逻辑,提高开发效率。但需要注意性能和安全问题,避免过度使用通配符。
阅读 0·2月21日 15:45

MQTT 和 HTTP 协议有什么区别?分别在什么场景下使用?

MQTT 与 HTTP 是两种常用的网络协议,它们在设计理念、应用场景和技术特点上有显著差异。设计理念对比MQTT设计目标:轻量级、低带宽、低功耗的消息传输协议通信模式:发布/订阅模式,一对多通信连接方式:长连接,保持持久连接传输方向:双向通信,服务器可以主动推送消息协议栈:应用层协议,基于 TCPHTTP设计目标:请求/响应模式的数据传输协议通信模式:客户端-服务器模式,一对一通信连接方式:短连接(HTTP/1.0)或长连接(HTTP/1.1 Keep-Alive)传输方向:单向通信,客户端主动请求协议栈:应用层协议,基于 TCP技术特点对比1. 消息传输| 特性 | MQTT | HTTP ||-----|------|------|| 传输模式 | 发布/订阅 | 请求/响应 || 消息方向 | 双向 | 单向(客户端→服务器) || 实时性 | 高 | 低(需要轮询或 WebSocket) || 消息大小 | 小(头部最小 2 字节) | 大(头部通常几百字节) || 带宽消耗 | 低 | 高 |2. 连接管理| 特性 | MQTT | HTTP ||-----|------|------|| 连接类型 | 长连接 | 短连接/长连接 || 连接保持 | Keep Alive 机制 | Keep-Alive(HTTP/1.1+) || 断线重连 | 自动重连 | 需要应用层处理 || 心跳机制 | 内置 PING/PONG | 无(需应用层实现) |3. 服务质量(QoS)| 特性 | MQTT | HTTP ||-----|------|------|| QoS 级别 | 3 级(0/1/2) | 无(依赖 TCP) || 消息确认 | 支持(PUBACK/PUBREC/PUBCOMP) | 无(依赖 TCP ACK) || 消息重传 | 支持 | 无(依赖 TCP 重传) || 消息顺序 | 保证 | 保证(TCP) |4. 安全性| 特性 | MQTT | HTTP ||-----|------|------|| 加密支持 | TLS/SSL(端口 8883) | HTTPS(端口 443) || 认证方式 | 用户名/密码、证书、Token | Basic Auth、Digest、OAuth || 访问控制 | ACL(主题级别) | 基于路径、权限系统 || 数据完整性 | 保证 | 保证 |性能对比1. 资源消耗| 指标 | MQTT | HTTP ||-----|------|------|| CPU 占用 | 低 | 中等 || 内存占用 | 低 | 中等 || 网络带宽 | 低 | 高 || 电池消耗 | 低 | 高 || 数据包大小 | 小 | 大 |2. 并发能力| 指标 | MQTT | HTTP ||-----|------|------|| 单连接消息数 | 高 | 低 || 并发连接数 | 高(百万级) | 中等(万级) || 消息吞吐量 | 高 | 中等 || 延迟 | 低(毫秒级) | 中等(百毫秒级) |应用场景对比MQTT 适用场景物联网设备传感器数据采集智能家居控制工业自动化车联网实时通信即时消息实时监控在线游戏聊天应用推送通知移动应用推送消息通知警报系统HTTP 适用场景Web 应用网页浏览API 调用文件下载表单提交数据传输RESTful API文件上传/下载大数据传输媒体流企业应用企业系统集成微服务通信数据同步业务流程代码示例对比MQTT 消息发布import paho.mqtt.client as mqttclient = mqtt.Client()client.connect("broker.example.com", 1883)client.publish("sensor/temperature", "25.5")client.disconnect()HTTP 请求import requestsresponse = requests.post( "https://api.example.com/sensor/temperature", json={"value": 25.5})print(response.status_code)优缺点总结MQTT 优点轻量级,适合资源受限设备低带宽,低功耗实时性好,支持双向通信支持一对多消息分发内置 QoS 保证适合物联网场景MQTT 缺点不适合大数据传输不适合文件传输不适合复杂查询生态系统相对较小HTTP 优点通用性强,生态丰富支持大数据传输支持复杂查询标准化程度高易于调试和监控支持缓存HTTP 缺点头部开销大实时性差(需要轮询)不适合低带宽环境服务器不能主动推送资源消耗较高选择建议选择 MQTT 的情况需要实时双向通信设备资源受限(低带宽、低功耗)需要一对多消息分发物联网应用需要离线消息支持网络不稳定环境选择 HTTP 的情况需要传输大数据需要复杂查询和过滤Web 应用开发RESTful API 设计需要广泛的工具支持需要缓存机制混合使用在实际应用中,可以结合使用 MQTT 和 HTTP:MQTT:用于实时数据传输、设备控制、状态更新HTTP:用于配置管理、数据查询、文件传输、API 访问例如:传感器数据通过 MQTT 实时上报历史数据查询通过 HTTP API设备配置通过 HTTP RESTful API告警通知通过 MQTT 实时推送MQTT 和 HTTP 各有优势,根据具体应用场景选择合适的协议,或者结合使用以发挥各自优势。
阅读 0·2月21日 15:45

MQTT Broker 的主要功能有哪些?常用的 MQTT Broker 实现有哪些?

MQTT Broker 是 MQTT 协议的核心组件,负责消息的接收、路由和分发。以下是 MQTT Broker 的主要功能和常用实现。Broker 的核心功能1. 连接管理客户端连接:接受和处理来自客户端的连接请求认证授权:验证客户端身份,控制访问权限会话管理:维护客户端会话状态心跳检测:通过 Keep Alive 机制检测客户端存活状态2. 消息路由主题匹配:根据订阅关系匹配消息主题消息分发:将消息转发给订阅该主题的所有客户端QoS 处理:确保消息按照指定的 QoS 级别传递消息过滤:支持基于主题和内容的消息过滤3. 持久化存储离线消息:存储离线客户端的订阅消息消息队列:临时存储待分发的消息会话状态:保存客户端的订阅关系和未确认消息消息日志:记录消息传输历史4. 安全机制TLS/SSL 加密:保护数据传输安全用户认证:支持用户名/密码、证书等多种认证方式访问控制:基于主题和客户端的权限管理ACL(访问控制列表):细粒度的权限控制5. 性能优化消息压缩:减少网络传输开销批量处理:提高消息处理效率负载均衡:支持集群部署,分散请求压力连接池:复用网络连接,降低资源消耗常用 MQTT Broker 实现1. Mosquitto特点:轻量级、开源、易于部署语言:C 语言实现适用场景:嵌入式设备、小型项目优点:资源占用少配置简单社区活跃缺点:性能相对较低企业级功能有限2. EMQX特点:高性能、分布式、企业级语言:Erlang/OTP 实现适用场景:大规模物联网平台、企业应用优点:支持百万级并发连接内置规则引擎丰富的管理界面支持集群和负载均衡缺点:学习曲线较陡资源占用较高3. HiveMQ特点:商业级、高性能、可扩展语言:Java 实现适用场景:企业级应用、金融、医疗优点:高性能和稳定性企业级支持和服务丰富的插件生态缺点:商业版本收费资源占用较高4. VerneMQ特点:高性能、分布式、可扩展语言:Erlang 实现适用场景:大规模实时通信优点:高并发支持灵活的插件系统支持集群部署缺点:文档相对较少社区规模较小5. RabbitMQ(MQTT 插件)特点:多功能消息代理语言:Erlang 实现适用场景:需要多种协议支持的系统优点:支持多种协议(AMQP、MQTT、STOMP)成熟稳定丰富的管理工具缺点:MQTT 功能相对基础性能不如专用 BrokerBroker 选择建议小型项目/原型开发推荐:Mosquitto理由:轻量、简单、免费中型项目/企业应用推荐:EMQX 社区版理由:功能丰富、性能良好、免费大规模物联网平台推荐:EMQX 企业版或 HiveMQ理由:高性能、企业级支持、可扩展需要多协议支持推荐:RabbitMQ理由:协议支持全面、成熟稳定性能指标对比| Broker | 并发连接数 | 消息吞吐量 | 资源占用 | 部署复杂度 ||--------|-----------|-----------|---------|-----------|| Mosquitto | 1万+ | 10万+ | 低 | 简单 || EMQX | 100万+ | 100万+ | 中 | 中等 || HiveMQ | 100万+ | 100万+ | 高 | 中等 || VerneMQ | 100万+ | 100万+ | 中 | 中等 || RabbitMQ | 10万+ | 10万+ | 中 | 中等 |选择 MQTT Broker 时,需要综合考虑项目规模、性能要求、预算和技术团队能力等因素。
阅读 0·2月21日 15:45

MQTT 5.0 相比 MQTT 3.1.1 有哪些新特性?

MQTT 5.0 版本在 3.1.1 版本的基础上进行了重大改进,引入了许多新特性,显著提升了协议的功能性和灵活性。MQTT 5.0 主要新特性1. 属性(Properties)定义:在控制报文中携带键值对形式的元数据作用:扩展协议功能,无需修改协议格式应用场景:消息过期时间请求/响应模式订阅标识符内容类型用户属性(自定义元数据)2. 请求/响应模式(Request/Response Pattern)相关属性:Response Topic:指定响应消息的主题Correlation Data:关联请求和响应工作流程:客户端发送请求消息,包含 Response Topic 和 Correlation Data服务端处理请求服务端发送响应消息到 Response Topic,包含相同的 Correlation Data客户端根据 Correlation Data 匹配响应优势:简化应用层实现减少自定义协议开发提高互操作性3. 会话和消息过期会话过期:Session Expiry Interval:指定会话过期时间(秒)0 表示立即过期,4294967295 表示永不过期替代了 Clean Session 标志消息过期:Message Expiry Interval:指定消息过期时间(秒)Broker 不再分发过期消息减少无效消息传输优势:更灵活的会话管理自动清理过期资源减少存储压力4. 共享订阅(Shared Subscriptions)语法:$share/<group>/<topic>示例:$share/consumer1/sensor/data工作原理:多个订阅者组成一个共享组每条消息只分发给组中的一个订阅者实现负载均衡优势:提高消息处理能力实现消费者扩展避免消息重复处理应用场景:高吞吐量数据处理分布式任务处理微服务架构5. 订阅标识符(Subscription Identifier)定义:为订阅分配一个数字标识符特点:每个客户端可以有多个订阅标识符标识符范围:1-268435455在 PUBLISH 报文中返回匹配的订阅标识符应用场景:区分不同的订阅实现复杂的消息路由简化应用逻辑6. 主题别名(Topic Alias)定义:用数字代替完整的主题字符串机制:客户端和 Broker 独立维护别名映射别名范围:1-65535在 CONNECT 或 PUBLISH 中声明优势:减少网络传输量降低带宽消耗提高传输效率应用场景:长主题名称高频消息传输带宽受限环境7. 流量控制(Flow Control)接收最大值(Receive Maximum):客户端指定未确认 PUBLISH 报文的最大数量防止消息积压默认值:65535最大数据包大小(Maximum Packet Size):限制最大数据包大小防止大包攻击默认值:无限制优势:防止资源耗尽提高系统稳定性适应不同网络条件8. 原因码(Reason Codes)定义:更详细的错误和状态信息范围:0x00-0xFF分类:成功码(0x00-0x00)错误码(0x80-0xFF)优势:更精确的错误诊断更好的问题排查改进的互操作性9. 认证增强(Enhanced Authentication)认证方法(Authentication Method):指定认证方法(如 SCRAM)支持多种认证协议认证数据(Authentication Data):携带认证相关的数据支持多轮认证重新认证(Re-authentication):在连接期间重新认证无需断开连接优势:更灵活的认证机制支持现代认证协议提高安全性10. 服务器断开(Server Disconnect)功能:服务器主动断开客户端连接原因码:说明断开原因服务器引用:提供服务器信息应用场景:服务器维护强制下线负载均衡MQTT 3.1.1 vs MQTT 5.0 对比| 特性 | MQTT 3.1.1 | MQTT 5.0 ||-----|-----------|----------|| 属性支持 | 无 | 支持 || 请求/响应 | 自定义实现 | 原生支持 || 会话管理 | Clean Session | Session Expiry || 共享订阅 | Broker 扩展 | 标准特性 || 主题别名 | 无 | 支持 || 流量控制 | 无 | 支持 || 错误码 | 简单 | 详细 || 认证机制 | 基础 | 增强 || 消息过期 | 无 | 支持 || 服务器断开 | 无 | 支持 |迁移建议向后兼容性MQTT 5.0 客户端可以连接到 MQTT 3.1.1 BrokerMQTT 3.1.1 客户端可以连接到 MQTT 5.0 Broker新特性仅在双方都支持时生效迁移策略评估需求:确定是否需要新特性逐步迁移:先升级 Broker,再升级客户端测试验证:充分测试兼容性和功能监控观察:监控迁移后的系统表现应用场景适合使用 MQTT 5.0 的场景需要请求/响应模式的应用高并发、高吞吐量的物联网平台需要精确错误诊断的系统需要灵活认证机制的企业应用带宽受限的物联网设备可以继续使用 MQTT 3.1.1 的场景简单的传感器数据采集低频率的消息传输已有稳定运行的系统资源极度受限的设备MQTT 5.0 的引入显著提升了协议的功能性和灵活性,为更复杂的物联网应用提供了更好的支持。
阅读 0·2月21日 15:45

MQTT 的遗嘱消息(Last Will)是什么?如何使用?

MQTT 的遗嘱消息(Last Will and Testament,LWT)是一种重要的机制,用于在客户端异常断开连接时通知其他客户端。遗嘱消息的概念定义遗嘱消息是客户端在连接时预先设置的一条消息,当客户端异常断开连接时,Broker 会自动将这条消息发布到指定的主题。作用异常检测:通知其他客户端某个设备已离线状态通知:发布设备离线状态故障告警:触发告警机制资源清理:通知系统清理相关资源遗嘱消息的工作原理设置遗嘱消息客户端在发送 CONNECT 报文时设置遗嘱消息参数:CONNECT 报文参数:- Will Flag: true(启用遗嘱消息)- Will Topic: 遗嘱消息的主题- Will Message: 遗嘱消息的内容- Will QoS: 遗嘱消息的 QoS 级别- Will Retain: 是否保留遗嘱消息触发条件遗嘱消息在以下情况下会被触发:客户端异常断开网络故障设备断电程序崩溃连接超时Broker 检测到连接断开Keep Alive 超时TCP 连接断开心跳检测失败不触发的情况以下情况不会触发遗嘱消息:正常断开连接客户端发送 DISCONNECT 报文正常关闭连接连接未建立CONNECT 报文发送失败连接被拒绝遗嘱消息的参数Will Flag(遗嘱标志)作用:标识是否启用遗嘱消息值:true/false必需:启用遗嘱消息时必须为 trueWill Topic(遗嘱主题)作用:指定遗嘱消息发布的主题格式:标准的 MQTT 主题字符串示例:device/123/status要求:必须设置Will Message(遗嘱消息内容)作用:遗嘱消息的实际内容格式:二进制数据示例:offline 或 {"status":"offline","timestamp":1234567890}要求:必须设置Will QoS(遗嘱 QoS)作用:指定遗嘱消息的 QoS 级别值:0/1/2默认值:0选择建议:QoS 0:一般状态通知QoS 1:重要状态通知QoS 2:关键状态通知Will Retain(遗嘱保留)作用:指定是否保留遗嘱消息值:true/false默认值:false影响:true:新订阅者会收到遗嘱消息false:只有在线订阅者收到遗嘱消息使用场景1. 设备在线状态监控设备上线:- 发布 "online" 到 device/123/status设备离线(正常):- 发布 "offline" 到 device/123/status设备离线(异常):- 遗嘱消息 "offline" 发布到 device/123/status2. 故障告警遗嘱主题:alert/device/123遗嘱消息:{"type":"offline","device":"123","timestamp":1234567890}监控系统订阅 alert/device/123收到遗嘱消息后触发告警3. 资源清理遗嘱主题:cleanup/device/123遗嘱消息:{"device":"123","action":"cleanup"}清理服务订阅 cleanup/device/123收到遗嘱消息后清理相关资源4. 负载均衡遗嘱主题:worker/offline遗嘱消息:{"worker":"worker1"}负载均衡器订阅 worker/offline收到遗嘱消息后重新分配任务代码示例Python (paho-mqtt)import paho.mqtt.client as mqttimport jsonimport timedef on_connect(client, userdata, flags, rc): print(f"Connected with result code {rc}") client.subscribe("device/+/status")def on_message(client, userdata, msg): print(f"Received: {msg.topic} - {msg.payload.decode()}")client = mqtt.Client()# 设置遗嘱消息will_topic = "device/123/status"will_message = json.dumps({"status": "offline", "timestamp": int(time.time())})client.will_set(will_topic, will_message, qos=1, retain=True)client.on_connect = on_connectclient.on_message = on_messageclient.connect("broker.example.com", 1883, 60)# 发布在线状态client.publish("device/123/status", json.dumps({"status": "online"}))client.loop_forever()JavaScript (MQTT.js)const mqtt = require('mqtt');const client = mqtt.connect('mqtt://broker.example.com', { will: { topic: 'device/123/status', payload: JSON.stringify({ status: 'offline', timestamp: Date.now() }), qos: 1, retain: true }});client.on('connect', () => { console.log('Connected'); // 发布在线状态 client.publish('device/123/status', JSON.stringify({ status: 'online' })); // 订阅状态主题 client.subscribe('device/+/status');});client.on('message', (topic, message) => { console.log(`Received: ${topic} - ${message.toString()}`);});最佳实践1. 遗嘱消息设计简洁明了:消息内容简洁,易于解析包含时间戳:便于追踪离线时间设备标识:明确标识是哪个设备状态信息:包含详细的离线原因2. 主题命名规范推荐格式:- device/{device_id}/status- alert/{device_id}/offline- cleanup/{device_id}避免使用:- 通配符作为遗嘱主题- 过于复杂的主题结构3. QoS 选择一般设备:QoS 0重要设备:QoS 1关键设备:QoS 24. Retain 设置状态监控:建议设置为 true告警通知:建议设置为 false资源清理:根据需求设置5. 遗嘱消息处理及时处理:收到遗嘱消息后及时处理避免重复:防止重复处理同一设备的离线事件记录日志:记录离线事件,便于问题排查注意事项正常断开:正常断开连接时,应该先发送 DISCONNECT 报文,避免触发遗嘱消息遗嘱消息更新:重新连接时可以更新遗嘱消息内容Broker 限制:某些 Broker 可能对遗嘱消息有大小限制网络延迟:网络延迟可能导致遗嘱消息延迟发送多设备场景:在多设备场景中,需要明确区分不同设备的遗嘱消息遗嘱消息的局限性无法区分离线原因:遗嘱消息不包含具体的离线原因可能误报:网络抖动可能导致误报处理延迟:从离线到发送遗嘱消息可能有延迟依赖 Broker:完全依赖 Broker 的可靠性MQTT 遗嘱消息是物联网应用中非常重要的机制,合理使用可以有效监控设备状态,提高系统的可靠性和可维护性。
阅读 0·2月21日 15:45

MQTT 的发布/订阅模式是如何工作的?

MQTT 的发布/订阅模式是一种消息传递架构,它解耦了消息的生产者和消费者,实现了灵活的一对多通信。核心概念1. 主题(Topic)定义:主题是消息的路由地址,采用层级结构格式:使用斜杠(/)分隔的字符串,如 home/livingroom/temperature特点:层级清晰,便于组织和管理支持通配符订阅大小写敏感长度限制:最多 65535 字节2. 发布者(Publisher)角色:消息的生产者功能:向特定主题发送消息特点:不需要知道订阅者的存在可以同时向多个主题发布消息发布后立即返回,不等待订阅者响应3. 订阅者(Subscriber)角色:消息的消费者功能:订阅感兴趣的主题,接收相关消息特点:可以订阅多个主题可以使用通配符订阅一类主题只接收订阅后发布的消息4. Broker(代理服务器)角色:消息的中转站和路由器功能:接收发布者发送的消息根据订阅关系将消息分发给订阅者管理客户端连接和会话处理消息的 QoS 保证工作流程连接建立:客户端(发布者/订阅者)连接到 Broker订阅主题:订阅者向 Broker 发送订阅请求发布消息:发布者向特定主题发送消息消息路由:Broker 接收消息,查找订阅该主题的客户端消息分发:Broker 将消息转发给所有订阅者消息接收:订阅者接收并处理消息通配符订阅单级通配符(+)匹配单个层级示例:home/+/temperature 匹配 home/livingroom/temperature,但不匹配 home/livingroom/kitchen/temperature多级通配符(#)匹配多个层级,必须放在主题末尾示例:home/# 匹配 home/ 下的所有主题优势解耦性:发布者和订阅者完全解耦,互不依赖灵活性:支持一对多、多对一、多对多的通信模式可扩展性:易于添加新的发布者和订阅者异步性:发布者不需要等待订阅者响应高效性:Broker 负责消息路由,减少网络开销与点对点模式的对比| 特性 | 发布/订阅模式 | 点对点模式 ||-----|-------------|-----------|| 耦合度 | 低 | 高 || 消息接收者 | 多个 | 一个 || 消息持久化 | 可选 | 通常需要 || 复杂度 | 中等 | 简单 || 适用场景 | 广播、通知 | 直接通信 |MQTT 的发布/订阅模式使其成为物联网、实时通信和消息推送等场景的理想选择。
阅读 0·2月21日 15:45

MQTT 的保留消息(Retained Messages)是什么?如何使用?

MQTT 的保留消息(Retained Messages)是一种特殊的消息机制,允许 Broker 保存最新消息,供新订阅者接收。保留消息的概念定义保留消息是 Broker 持久化存储的消息,当有新的客户端订阅该主题时,Broker 会立即将保留消息发送给该客户端。作用状态同步:新订阅者可以立即获取最新状态初始化数据:为新连接的客户端提供初始数据状态恢复:帮助客户端快速恢复到最新状态减少请求:避免客户端主动请求最新状态保留消息的工作原理设置保留消息发布消息时设置 Retain 标志:PUBLISH 报文参数:- Topic: 主题名称- Payload: 消息内容- QoS: QoS 级别- Retain: true(设置为保留消息)保留消息的存储存储位置:Broker 内存或持久化存储存储数量:每个主题只保留一条最新消息存储覆盖:新发布的保留消息会覆盖之前的保留消息保留消息的发送当客户端订阅主题时:客户端发送 SUBSCRIBE 报文Broker 检查该主题是否有保留消息如果有,立即发送保留消息给客户端然后发送后续的新消息保留消息的特性1. 每个主题一条规则:每个主题只保留一条最新的保留消息覆盖机制:新发布的保留消息会替换之前的清除机制:发布空消息(Payload 为空)可以清除保留消息2. QoS 级别继承性:保留消息的 QoS 级别由发布时决定订阅限制:订阅者接收的 QoS 级别受限于订阅时的 QoS 设置QoS 规则:实际 QoS = min(发布 QoS, 订阅 QoS)3. 持久化内存存储:默认存储在内存中持久化存储:可配置持久化到磁盘Broker 重启:持久化的保留消息在 Broker 重启后仍然存在4. 消息顺序发送顺序:保留消息在普通消息之前发送订阅时机:只在订阅时发送一次后续消息:不重复发送保留消息使用场景1. 设备状态同步场景:温度传感器保留主题:sensor/123/temperature保留消息:{"value": 25.5, "unit": "C", "timestamp": 1234567890}新订阅者订阅 sensor/123/temperature立即收到最新温度值2. 配置信息发布场景:设备配置保留主题:config/device/123保留消息:{"mode": "auto", "interval": 60}新设备上线订阅配置主题立即获取最新配置3. 系统状态广播场景:系统状态保留主题:system/status保留消息:{"status": "running", "version": "1.0.0"}新客户端订阅系统状态立即获取当前系统状态4. 开关状态场景:智能开关保留主题:switch/123/state保留消息:{"state": "on"}新订阅者立即获取开关状态代码示例Python (paho-mqtt)import paho.mqtt.client as mqttimport jsonimport timedef on_connect(client, userdata, flags, rc): print(f"Connected with result code {rc}") # 订阅主题 client.subscribe("sensor/+/temperature")def on_message(client, userdata, msg): print(f"Received: {msg.topic} - {msg.payload.decode()}") print(f"Retained: {msg.retain}")# 发布保留消息client = mqtt.Client()client.connect("broker.example.com", 1883, 60)# 发布保留消息(retain=True)message = {"value": 25.5, "unit": "C", "timestamp": int(time.time())}client.publish("sensor/123/temperature", json.dumps(message), retain=True)# 清除保留消息(发布空消息)# client.publish("sensor/123/temperature", "", retain=True)client.disconnect()# 订阅者subscriber = mqtt.Client()subscriber.on_connect = on_connectsubscriber.on_message = on_messagesubscriber.connect("broker.example.com", 1883, 60)subscriber.loop_forever()JavaScript (MQTT.js)const mqtt = require('mqtt');// 发布保留消息const publisher = mqtt.connect('mqtt://broker.example.com');publisher.on('connect', () => { console.log('Publisher connected'); // 发布保留消息(retain: true) const message = JSON.stringify({ value: 25.5, unit: 'C', timestamp: Date.now() }); publisher.publish('sensor/123/temperature', message, { retain: true }); // 清除保留消息(发布空消息) // publisher.publish('sensor/123/temperature', '', { retain: true }); publisher.end();});// 订阅者const subscriber = mqtt.connect('mqtt://broker.example.com');subscriber.on('connect', () => { console.log('Subscriber connected'); subscriber.subscribe('sensor/+/temperature');});subscriber.on('message', (topic, message) => { console.log(`Received: ${topic} - ${message.toString()}`); console.log(`Retained: ${message.retain}`);});最佳实践1. 保留消息设计状态信息:保留消息应该表示当前状态简洁明了:消息内容简洁,易于解析包含时间戳:便于判断消息的新旧程度版本控制:可以包含版本信息2. 主题命名推荐格式:- sensor/{device_id}/temperature- config/{device_id}- status/{system_id}避免使用:- 通配符主题(不能发布到通配符主题)- 过于复杂的主题结构3. 消息大小限制大小:保留消息不宜过大建议大小:通常小于 1KBBroker 限制:注意 Broker 对消息大小的限制4. QoS 选择一般状态:QoS 0重要状态:QoS 1关键状态:QoS 25. 清除机制主动清除:发布空消息清除保留消息定期清理:定期检查和清理过期的保留消息生命周期管理:为保留消息设置合理的生命周期注意事项内存占用:保留消息会占用 Broker 内存,大量保留消息可能影响性能持久化配置:如果需要保留消息在 Broker 重启后仍然存在,需要配置持久化消息更新:频繁更新保留消息会增加 Broker 负担订阅时机:保留消息只在订阅时发送,不会重复发送QoS 限制:订阅者接收的 QoS 级别受限于订阅时的 QoS 设置空消息清除:发布空消息(Payload 为空)可以清除保留消息保留消息 vs 遗嘱消息| 特性 | 保留消息 | 遗嘱消息 ||-----|---------|---------|| 触发时机 | 订阅时 | 异常断开时 || 消息来源 | 发布者设置 | 客户端设置 || 存储位置 | Broker | Broker || 发送对象 | 新订阅者 | 订阅该主题的客户端 || 消息数量 | 每主题一条 | 每客户端一条 || 清除方式 | 发布空消息 | 正常断开或重新连接 |保留消息的局限性每主题一条:每个主题只能保留一条消息,无法保存历史消息内存占用:大量保留消息会占用较多内存实时性:保留消息可能不是最新的(取决于发布频率)无历史记录:无法获取历史状态变化依赖 Broker:完全依赖 Broker 的可靠性MQTT 保留消息是物联网应用中非常重要的机制,合理使用可以有效实现状态同步和初始化,提高用户体验和系统可靠性。
阅读 0·2月21日 15:44

MQTT 协议的安全机制有哪些?如何保证 MQTT 通信的安全性?

MQTT 协议提供了多种安全机制来保护消息传输的安全性,包括身份认证、访问控制和数据加密等方面。1. 传输层安全(TLS/SSL)TLS 加密作用:在传输层对数据进行加密,防止中间人攻击协议版本:支持 TLS 1.2 和 TLS 1.3端口:MQTT over TLS:默认端口 8883标准 MQTT:默认端口 1883(不加密)证书认证单向认证:客户端验证服务器证书服务器提供数字证书客户端验证证书有效性防止连接到伪造的 Broker双向认证:客户端和服务器互相验证证书提供更高的安全性适用于高安全要求场景需要为每个客户端颁发证书2. 身份认证机制用户名/密码认证基本认证:在 CONNECT 报文中携带用户名和密码特点:实现简单广泛支持密码明文传输(需配合 TLS 使用)配置示例: CONNECT Client ID: client123 Username: user Password: pass123Token 认证JWT Token:使用 JSON Web Token 进行认证特点:无状态认证支持过期时间可携带自定义信息适用场景:分布式系统、微服务架构OAuth 2.0 认证授权流程:使用 OAuth 2.0 标准进行授权特点:标准化的授权协议支持多种授权模式与现有身份系统集成方便证书认证客户端证书:使用 X.509 证书进行身份验证特点:安全性最高无需传输密码证书管理复杂适用场景:金融、医疗等高安全要求领域3. 访问控制(ACL)ACL 规则基于主题的权限:控制客户端对特定主题的访问权限类型:订阅(Subscribe):是否允许订阅主题发布(Publish):是否允许发布到主题读写(Read/Write):同时允许订阅和发布ACL 配置示例# 用户 user1 可以发布到 home/#user1 publish home/## 用户 user2 可以订阅 home/+/temperatureuser2 subscribe home/+/temperature# 管理员拥有所有权限admin publish #admin subscribe #ACL 实现方式静态配置:在配置文件中定义规则数据库存储:使用 MySQL、PostgreSQL 等数据库存储规则动态 API:通过 HTTP API 动态获取权限集成外部系统:与 LDAP、Active Directory 等集成4. 会话安全Clean SessionClean Session = true:断开连接后清除会话状态不保存离线消息适用于临时连接Clean Session = false:保留会话状态保存离线消息适用于持久连接会话超时Keep Alive:客户端定期发送心跳包超时处理:超过指定时间未收到心跳,断开连接默认值:通常为 60 秒5. 消息安全消息加密端到端加密:应用层对消息内容加密加密算法:AES、RSA 等适用场景:高敏感数据传输消息签名数字签名:验证消息来源和完整性防止篡改:确保消息未被修改适用场景:关键指令、控制命令6. 安全最佳实践网络层使用 TLS:始终使用 TLS 加密传输防火墙配置:限制 MQTT 端口访问网络隔离:将 MQTT Broker 放在内网VPN 访问:远程访问使用 VPN认证层强密码策略:使用复杂密码,定期更换多因素认证:对关键操作启用 MFA证书管理:定期更新证书,及时撤销过期证书最小权限原则:只授予必要的权限应用层输入验证:验证所有输入数据速率限制:防止暴力破解和 DDoS 攻击日志审计:记录所有操作日志安全监控:实时监控异常行为7. 常见安全威胁及防护威胁类型中间人攻击:使用 TLS 防护重放攻击:使用时间戳和随机数暴力破解:使用速率限制和账户锁定消息注入:使用消息签名和验证拒绝服务:使用连接数限制和资源配额防护措施定期安全审计:检查配置和日志漏洞扫描:定期扫描系统漏洞渗透测试:模拟攻击测试安全性安全更新:及时更新 Broker 和依赖库MQTT 的安全性需要从多个层面综合考虑,根据应用场景的安全要求选择合适的安全机制组合。
阅读 0·2月19日 19:18

MQTT 协议有哪些控制报文类型?各自的作用是什么?

MQTT 协议定义了多种控制报文类型,每种报文都有特定的功能和格式。以下是 MQTT 协议的主要控制报文及其作用。MQTT 控制报文类型1. CONNECT - 连接请求方向:客户端 → Broker作用:客户端向 Broker 请求建立连接关键参数:Client ID:客户端唯一标识符Clean Session:是否清除之前的会话状态Keep Alive:心跳间隔(秒)Username/Password:认证信息Will Message:遗嘱消息(客户端异常断开时发送)响应:CONNACK2. CONNACK - 连接确认方向:Broker → 客户端作用:确认连接是否成功建立关键参数:Session Present:是否包含之前的会话状态Return Code:连接结果(0 表示成功)返回码示例:0:连接成功1:协议版本不支持2:客户端 ID 不合法3:服务器不可用4:用户名或密码错误5:未授权3. PUBLISH - 发布消息方向:双向(客户端 ↔ Broker)作用:发布消息到指定主题关键参数:Topic Name:主题名称Packet Identifier:数据包标识符(QoS 1/2)QoS:服务质量级别(0/1/2)DUP:是否重复发送Retain:是否保留消息Payload:消息内容响应:QoS 0:无响应QoS 1:PUBACKQoS 2:PUBREC → PUBREL → PUBCOMP4. PUBACK - 发布确认(QoS 1)方向:接收方 → 发布方作用:确认收到 QoS 1 消息关键参数:Packet Identifier:对应的消息 ID5. PUBREC - 发布收到(QoS 2)方向:接收方 → 发布方作用:确认收到 QoS 2 消息的第一阶段关键参数:Packet Identifier:对应的消息 ID响应:PUBREL6. PUBREL - 发布释放(QoS 2)方向:发布方 → 接收方作用:释放 QoS 2 消息的第二阶段关键参数:Packet Identifier:对应的消息 ID响应:PUBCOMP7. PUBCOMP - 发布完成(QoS 2)方向:接收方 → 发布方作用:完成 QoS 2 消息的第三阶段关键参数:Packet Identifier:对应的消息 ID8. SUBSCRIBE - 订阅主题方向:客户端 → Broker作用:订阅一个或多个主题关键参数:Packet Identifier:数据包标识符Topic Filter:主题过滤器(支持通配符)QoS:订阅的 QoS 级别响应:SUBACK9. SUBACK - 订阅确认方向:Broker → 客户端作用:确认订阅结果关键参数:Packet Identifier:对应的 SUBSCRIBE 消息 IDReturn Codes:每个主题的订阅结果返回码示例:0-2:成功(QoS 级别)128:订阅失败10. UNSUBSCRIBE - 取消订阅方向:客户端 → Broker作用:取消订阅一个或多个主题关键参数:Packet Identifier:数据包标识符Topic Filter:要取消的主题过滤器响应:UNSUBACK11. UNSUBACK - 取消订阅确认方向:Broker → 客户端作用:确认取消订阅关键参数:Packet Identifier:对应的 UNSUBSCRIBE 消息 ID12. PINGREQ - 心跳请求方向:客户端 → Broker作用:检测连接是否活跃触发条件:Keep Alive 时间的一半响应:PINGRESP13. PINGRESP - 心跳响应方向:Broker → 客户端作用:响应心跳请求,确认连接正常响应时间:通常在 1 秒内14. DISCONNECT - 断开连接方向:客户端 → Broker作用:主动断开连接特点:正常断开,不发送遗嘱消息Broker 清除客户端状态(Clean Session = true)控制报文格式固定头部(Fixed Header)所有 MQTT 控制报文都包含固定头部:+-----------------+------------------+| Control Type | Flags || (4 bits) | (4 bits) |+-----------------+------------------+| Remaining Length (Variable) |+-------------------------------------+Control Type:控制报文类型(1-14)Flags:标志位,根据报文类型有不同的含义Remaining Length:剩余长度(可变长度编码)可变头部(Variable Header)某些报文包含可变头部,包含报文特定的信息:Packet IdentifierTopic NameProperties(MQTT 5.0)有效载荷(Payload)某些报文包含有效载荷:PUBLISH:消息内容CONNECT:客户端信息SUBSCRIBE:订阅列表QoS 级别与报文流程QoS 0 流程Client ──PUBLISH──> BrokerQoS 1 流程Client ──PUBLISH──> BrokerClient <─PUBACK─── BrokerQoS 2 流程Client ──PUBLISH──> BrokerClient <─PUBREC─── BrokerClient ──PUBREL──> BrokerClient <─PUBCOMP── Broker报文类型总结| 报文类型 | 方向 | QoS | 说明 ||---------|-----|-----|------|| CONNECT | 客户端 → Broker | - | 建立连接 || CONNACK | Broker → 客户端 | - | 连接确认 || PUBLISH | 双向 | 0/1/2 | 发布消息 || PUBACK | 双向 | 1 | 发布确认 || PUBREC | 双向 | 2 | 发布收到 || PUBREL | 双向 | 2 | 发布释放 || PUBCOMP | 双向 | 2 | 发布完成 || SUBSCRIBE | 客户端 → Broker | - | 订阅主题 || SUBACK | Broker → 客户端 | - | 订阅确认 || UNSUBSCRIBE | 客户端 → Broker | - | 取消订阅 || UNSUBACK | Broker → 客户端 | - | 取消确认 || PINGREQ | 客户端 → Broker | - | 心跳请求 || PINGRESP | Broker → 客户端 | - | 心跳响应 || DISCONNECT | 客户端 → Broker | - | 断开连接 |理解 MQTT 控制报文类型和流程对于实现 MQTT 客户端和服务器至关重要。
阅读 0·2月19日 19:17