MQTT学习笔记

MQTT 对比 HTTP

1、MQTT 的最小报文仅为 2 个字节,比 HTTP 占用更少的网络开销。
2、MQTT 与 HTTP 都能使用 TCP 连接,并实现稳定、可靠的网络连接。
3、MQTT 基于发布订阅模型,HTTP 基于请求响应,因此 MQTT 支持双工通信。
4、MQTT 可实时推送消息,但 HTTP 需要通过轮询获取数据更新。
5、MQTT 是有状态的,但是 HTTP 是无状态的。
6、MQTT 可从连接异常断开中恢复,HTTP 无法实现此目标。

MQTT的优点

三种消息服务质量等级(Quality of Service)

QoS 0:消息最多传递一次

只管发送1次,不管收到与否
在这里插入图片描述

消息可能丢失,原因:

消息的可靠性完全依赖于底层的 TCP 协议。

而 TCP 只能保证在连接稳定不关闭的情况下消息的可靠到达,一旦出现连接关闭、重置,仍有可能丢失当前处于网络链路或操作系统底层缓冲区中的消息。

QoS 1:消息传递至少 1 次

无限制重传,保证收到,可能收多次

在这里插入图片描述

消息可能重复,原因:

1、PUBLISH 未到达接收方
2、PUBLISH 已经到达接收方,接收方的 PUBACK 报文还未到达发送方

未收到PUBACK原因
(1)、Receiver—>Broker受阻
(2)、Broker—>Sender受阻

QoS 2:消息仅传送一次。

有条件的重传,保证到达一次。

在这里插入图片描述

消息保证不重复,原因:

QoS 1 中,仅有一个PUBLISH 和 PUBREC , 用于确定是否收到,只要收到就立刻释放了Packet ID,相同的ID无法分辨是重传还是新的消息。 所以遇到就都收,不敢拒收。

QoS 2 中,增加了PUBEREL和PURBCOMP报文。再上述之后,再次确认Packet ID是否可以释放、复用。所以可以确定相同ID一定是相同消息,因此可以拒收。

性能比较

0和1基本差不多,高负载情况1会稍慢。
2差不多是0、1的一半。

本部分参考自

https://www.emqx.com/zh/blog/introduction-to-mqtt-qos

MQTT工作流程

1、客户端使用 TCP/IP 协议与 Broker 建立连接,可以选择使用 TLS/SSL 加密来实现安全通信。客户端提供认证信息,并指定会话类型(Clean Session 或 Persistent Session)。

2、客户端既可以向特定主题发布消息,也可以订阅主题以接收消息。当客户端发布消息时,它会将消息发送给 MQTT Broker;而当客户端订阅消息时,它会接收与订阅主题相关的消息。

3、MQTT Broker 接收发布的消息,并将这些消息转发给订阅了对应主题的客户端。它根据 QoS 等级确保消息可靠传递,并根据会话类型为断开连接的客户端存储消息。

MQTT主题

主题通配符
单层通配符

+:表示单层通配符,例如 a/+ 匹配 a/x 或 a/y。
eg:

+ 有效
sensor/+ 有效
sensor/+/temperature 有效
sensor+ 无效(没有占据整个层级)
多层通配符

#:表示多层通配符,例如 a/# 匹配 a/x、a/b/c/d。

# 有效,匹配所有主题
sensor/# 有效
sensor/bedroom# 无效(没有占据整个层级)
sensor/#/temperature 无效(不是主题最后一个字符)

$开头的主题
系统主题

$SYS/ 开头的主题为系统主题
eg:

主题说明
$SYS/brokersEMQX 集群节点列表
$SYS/brokers/emqx@127.0.0.1/versionEMQX 版本
$SYS/brokers/emqx@127.0.0.1/uptimeEMQX 运行时间
$SYS/brokers/emqx@127.0.0.1/datetimeEMQX 系统时间
$SYS/brokers/emqx@127.0.0.1/sysdescrEMQX 系统信息
举例

在这里插入图片描述

共享订阅
即时消息
常见的 MQTT 主题使用建议有哪些?

1、不建议使用 # 订阅所有主题;
2、不建议主题以 / 开头或结尾,例如 /chat 或 chat/;
3、不建议在主题里添加空格及非 ASCII 特殊字符;
4、同一主题层级内建议使用下划线 _ 或横杆 - 连接单词(或者使用驼峰命名);
5、尽量使用较少的主题层级;
6、当使用通配符时,将唯一值的主题层(例如设备号)越靠近第一层越好。例如,device/00000001/command/# 比device/command/00000001/# 更好。

MQTT共享订阅

带群组的共享订阅

在这里插入图片描述

不带群组的共享订阅

在这里插入图片描述

共享订阅的负载均衡策略

即,共享订阅的几个设备之间,消息发给谁。

1、随机(Random),在共享订阅组内随机选择一个会话发送消息。
2、轮询(Round Robin),在共享订阅组内按顺序选择一个会话发送消息,循环往复。
3、哈希(Hash),基于某个字段的哈希结果来分配。
4、粘性(Sticky),在共享订阅组内随机选择一个会话发送消息,此后保持这一选择,直到该会话结束再重复这一过程。
5、本地优先(Local),随机选择,但优先选择与消息的发布者处于同一节点的会话,如果不存在这样的会话,则退化为普通的随机策略。
举例

这个地方我搜了半天网上没找到通俗的,期待大佬指正 指路。

1、一个自己想的不一定对的

共享家居,一个温度传感器,有2个手机、2个主控需要接受数据。因为对温度实时性要求不高,所以随机、轮转应该都可以。

2、来自GPT4,感觉不理解不知道对不对。。。
随机(Random)策略:
应用场景:假设有多个智能灯泡连接到同一个智能家居系统。当用户通过智能家居App发送一个“关闭所有灯泡”的指令时,系统可以使用随机策略随机选择一个在线的智能灯泡会话来传递关闭指令,因为实际上关闭任何一个灯泡的指令都是相同的。

轮询(Round Robin)策略:
应用场景:在一个有多个空调的房间中,为了均匀分摊空调的使用时间和维护成本,智能家居系统可能会使用轮询策略来依次控制每台空调的开关,确保每台空调都有均等的工作时间。

哈希(Hash)策略:
应用场景:智能家居系统中的多个音响可能需要根据房间的位置播放不同的音乐。系统可以根据房间号(或其他唯一标识符)的哈希值将播放指令发送到对应的音响,保证每个房间都能播放适当的音乐。

粘性(Sticky)策略:
应用场景:假设智能家居系统中的安防摄像头需要发送定期的状态更新。系统可以为每个摄像头分配一个会话,并使用粘性策略在摄像头的生命周期内维持这个会话,确保状态更新始终通过同一通道发送,直到摄像头关闭或会话结束。

本地优先(Local)策略:
应用场景:在分布式智能家居系统中,如果有多个中心节点,每个节点管理着不同的设备群组。一个节点可能需要向其他节点发送数据,但如果目标设备与发送者在同一节点下,系统会使用本地优先策略。这样可以减少网络延迟,提高效率。例如,如果节点A和节点B都有智能窗帘,当节点A收到关闭所有窗帘的指令时,它会优先关闭自己节点下的窗帘,然后再将指令通过网络发送给节点B。

注意事项
1、在共享订阅组内使用相同的 QoS

MQTT 虽然允许一个共享订阅组内的会话使用不同的 QoS 等级,但这可能会使消息在投递给同一个组内的不同会话时存在不同的质量保证。相应地,在出现一些问题的时候,我们的调试也将变得困难重重。所以我们最好在共享订阅组内使用相同的 QoS。

2、合理地设置会话过期时间

共享订阅+持久回话中,即使某一个客户端挂了,仍要向其分发消息。因此会导致消息因为被投递给离线客户端而无法得到处理。

一个更好的选择可能是,一旦订阅端离线,即便会话没有过期,MQTT 服务端在分配消息负载时也不再考虑这个订阅端。虽然与普通订阅的行为不同,但这是 MQTT 协议允许的。

参考链接

https://www.emqx.com/zh/blog/introduction-to-mqtt5-protocol-shared-subscription

https://www.emqx.io/docs/zh/latest/messaging/mqtt-shared-subscription.html

MQTT 发布/订阅模式

组成
发布者(Publisher)

负责将消息发布到主题上,发布者一次只能向一个主题发送数据,发布者发布消息时也无需关心订阅者是否在线。

订阅者(Subscriber)

订阅者通过订阅主题接收消息,且可一次订阅多个主题。MQTT 还支持通过共享订阅的方式在多个订阅者之间实现订阅的负载均衡。

代理(Broker)

负责接收发布者的消息,并将消息转发至符合条件的订阅者。另外,代理也需要负责处理客户端发起的连接、断开连接、订阅、取消订阅等请求。

主题(Topic)

主题是 MQTT 进行消息路由的基础,它类似 URL 路径,使用斜杠 / 进行分层,比如 sensor/1/temperature。一个主题可以有多个订阅者,代理会将该主题下的消息转发给所有订阅者;一个主题也可以有多个发布者,代理将按照消息到达的顺序转发。

消息路由 过滤消息方式
根据主题

订阅者向代理订阅自己感兴趣的主题,发布者发布的所有消息中都会包含自己的主题,代理根据消息的主题判断需要将消息转发给哪些订阅者。

根据消息内容

订阅者定义其感兴趣的消息的条件,只有当消息的属性或内容满足订阅者定义的条件时,消息才会被投递到该订阅者。

MQTT 协议是基于主题进行消息路由的,在这个基础上,EMQX 从 3.1 版本开始通过基于 SQL 的规则引擎提供了额外的按消息内容进行路由的能力。

MQTT认证方式

参考此文学习

账号密码认证
裸的传,容易被干,不安全。
使用Salt 和 Hash为密码加密,再通过TLS传输。
TOKEN认证

TOKEN是一个凭证,仅验证身份、有效期等,更加安全便于管控。
具体实现见此文

  • 20
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值