MQTT物联网应用的首选协议。基于发布/订阅模式,它简化了设备之间的连接。我们之前的一篇文章介绍了MQTT的基础知识。在这一部分中,我们将介绍MQTT架构如何确保消息得到传递,以及当事情不那么顺利时,它提供了哪些可能的处理方式。
MQTT是一个轻量级协议,它使用发布/订阅模式来连接感兴趣的各方。它通过将发送者(发布者)与接收者(订阅者)解耦来实现。发布者向一个中心主题发送消息,该中心主题有多个订阅者等待接收消息。发布者和订阅者是自主的,这意味着他们不需要知道对方的存在。
了解服务质量(QoS)
MQTT是一个轻量级的协议,但它仍被用于一些要求可靠传递消息的复杂场景中。客户端可以配置不同级别的服务质量(QoS),以确保可靠的消息传递。由于它是规范的一部分,所以在标准的MQTT代理应该实现这一功能。
与其他面向服务的环境类似,MQTT中的QoS是代理和客户端之间的协议。当他们双方就特定的QoS级别达成一致时,就隐含着代理履行规定的意思。
MQTT中的QoS有三个级别。
QoS 0 最多交付一次。
QoS 1:至少交付一次。
QoS 2:精确一次交付。
QoS 0:最多交付一次。
这是客户端和代理使用的默认服务质量水平,它并不能保证消息的传递。在MQTT中,消息的发送取决于网络能力和连接性。用户要确认收到,而发布者不需要重试发送。消息可能会或根本不会到达用户。在网络可靠且偶尔丢失消息可以接受的环境中,QoS 0是首选。例如,当多个温度传感器每10秒发布一次消息时,丢失几个消息不会对系统产生多大影响。
![MQTT协议的消息传递可靠性和持续性 1](https://blog.digiinfr.com/wp-content/uploads/2020/11/MQTT_QOS0.png)
QoS 1:至少交付一次
这种服务质量确保信息至少一次到达接收方。未确保送达,会重试多轮,订阅者可能多次收到相同的消息。订阅者代理商确认收到消息,代理将停止重试传递。QoS 1用于保证消息交付很重要的场景。接收相同的消息多次(收到重复消息)是可以接受的,但至少应该交付一次。
该QoS级别配置在定期报告关键设备或系统状态的远程监控场景中。这是最常用的QoS级别。
![MQTT协议的消息传递可靠性和持续性 2](https://blog.digiinfr.com/wp-content/uploads/2020/11/MQTT_QOS1.png)
QoS 2:精确地交付一次(不重复)
QoS 2提供了最高的服务质量,在这种情况下,信息的丢失或重复都是不可接受的。它伴随着与可靠服务质量相关的开销增加。虽然这可能是最可靠的QoS,但它也是最慢的。QoS 2应少用于要求保证消息交付的特定客户机。它用于无法承受丢失消息或接收重复消息的关键任务场景。架构师和开发人员在使用QoS 2时应注意性能权衡。 对于大多数部署,QoS 1就足够了。
![MQTT协议的消息传递可靠性和持续性 3](https://blog.digiinfr.com/wp-content/uploads/2020/11/MQTT_QoS2.png)
QoS 2是最安全,但最慢的传输模式。
重要的是要了解每个订阅主题的客户端可以请求不同级别的QoS。MQTT代理可以为订阅同一主题的每个客户端维护不同的QoS级别。由于客户端(发布者和订阅者)在MQTT中是自主的,它们可以独立使用不同的QoS级别。发布者可以使用与订阅者完全不同的QoS级别。
持久性(Persistence)
尽管MQTT不是一个完整的面向消息的中间件,但它支持消息的持久性。当处理在受限环境中运行的客户端时,这个功能变得至关重要。
每次客户端连接到MQTT代理时,它都会启动一个新的会话来订阅或发布到主题。如果连接丢失,这个过程会重新开始,客户端会建立一个新的会话。这个过程可能会干扰系统的性能,特别是对于那些处理能力低和连接断断续续的客户端。这就是MQTT broker的持久性功能变得有用的地方。
当客户端连接到MQTT代理时,它可以将 “Clean Session “标志设置为false,表示即使客户端断开连接后,MQTT代理也应该保留会话信息。然后,MQTT代理开始为该客户端持久化会话。每个会话都包含详细信息,如客户端订阅或发布的主题、客户端离线时发送的 QoS 1 和 QoS 2 消息,以及客户端尚未确认的 QoS 2 消息。
- QoS 0 消息不持久。消息没有存储在服务器上。如果发布者断开连接,或者服务器发生故障,消息可能会丢失。如果用户在服务器接收发布的消息时已断开连接,则用户可能不会收到消息。
- QoS 1、2 消息是持久性的。消息存储在服务器上,直到消息被发送到消息的所有订阅者。如果消息订阅者请求的QoS需要确认,则消息将被存储,直到收到确认为止。
持久性在确保MQTT代理满足QoS 1和QoS 2方面也起着重要作用。这个功能必须少用,因为它会干扰MQTT代理的性能。
保留的信息(Retained Messages)
请记住,在MQTT中,客户端是自主的,它不承认对方的存在。这也意味着,当一个用户连接到代理时,它不知道什么时候会收到消息。有许多不是一个发布者向该主题发送消息,或者发布者可能长期离线。
在某些场景下,发布者在连接到代理后,立即与所有新用户分享最后一条消息是有意义的。例如,当一个移动应用(发布者)向多个连接的灯泡(订阅者)发送亮度和颜色值的消息时,它希望新灯泡被设置为相同的值。因此,当一个新的灯泡连接到MQTT代理时,它将收到所有其他灯泡会收到的最后一条消息。这确保了现有订户和新订户的状态是相同的。
遗嘱(Last Will and Testament-LWT)
客户端突然与代理人断开连接的情况很常见。设备可能失去电源或网络连接,迫使它断开连接。在很多情况下,让其他客户知道某个特定客户突然结束会话可能会有帮助。
MQTT代理提供了一个强大的功能,称为遗嘱(LWT),它使客户能够主动选择一个主题和消息,当它被断开连接时,将被发布。有兴趣的客户可以订阅LWT主题,当客户被不优雅地断开连接时,他们将立即得到经纪人的通知。
例如,当一个移动应用(发布者)失去连接时,所有被该应用控制的设备都会收到该应用离线的消息。当移动应用获得连接性时,它可以向同一主题发布保留消息,告知客户它已经在线。要知道,LWT话题和消息并不是特殊的,也不是保留的。客户端可以像其他主题一样向它发布消息。
LWT话题和消息提供了一种机制,让所有感兴趣的客户端知道特定客户端的状态。