【译文】持久化会话与纯净式会话-MQTT基础:第七部分

207 阅读9分钟

原文:www.hivemq.com/blog/mqtt-e…

本篇文章在翻译过程中,对相关内容进行了一些删减,比如文字超链接

作者: HiveMQ Team
发布时间: February 23, 2015
更新于: 2023年6月27日

MQTT中的持久会话机制允许客户端去维护它的订阅信息和穿插在多个连接中的消息状态。当客户端在多个连接中和代理服务器建立了持久会话,代理服务器会保存客户端的订阅信息和任何没有传递成功的消息。采用持久会话机制后,如果客户端稍后断开连接重连,它将继续之前的通信。这篇文章是基础课程系列的第七部分,基础课程共分10部,涵盖MQTT协议的核心特性,概念,优势。本篇文章我们要探究持久会话话题,清除会话及消息队列。我们将深入研究MQTT中的持久会话如何通过启用可靠的消息传递、提供QoS保障以及促进客户端的高效重连接(即使存在间歇性连接或客户端断开连接)来增强QoS。

如果你对MQTT Quality of Service (QoS) 0,1, & 2是一个新手, 可以查阅一下第六部分课程,或者直接开始本章的学习。

持久化会话指的是什么?

为了从MQTT代理服务器接收消息,客户端需要先连接和订阅一个预期的主题。在没有持久化会话下,如果客户端和代理服务器连接被中断,客户端将丢失他的订阅信息,重新连接后需要再次订阅。这对资源受限的客户端来说是一种负担。 为了解决这个问题,客户端在连接代理服务器时,可以要求会话持久化

持久化会话会把所有与客户端相关的信息保存在代理服务器上,确保订阅信息和消息在客户端离线时依然可以保留下来。建立连接后,会话可以客户端提供的客户端ID来做为标识。为了学习更多,请阅读MQTT Client, MQTT Broker, and MQTT Server Connection Establishment Explained.

持久化会话存储的是什么信息?

在一个持久化会话中,代理服务器会存储如下信息(即使客户端已离线)。在客户端再次连接后,这些信息会立即再次生效:

  • 会话存在信息(即使没有订阅) : 代理服务服务器会保留已存在的会话信息,允许客户端再次连接成功后,恢复之前的会话状态。
  • 所有客户端的订阅信息: 代理服务器会存储客户端已订阅的主题列表,这能保证客户端再次连接后,无需再次订阅主题,可以节省时间和资源。
  • 还没被客户端确认的所有QoS 1 ,QoS 2级别的信息流: 代理服务器会把QoS 1和QoS 2级别下的未确认信息发送给客户端。这些信息在客户端重新连接上之前,会一直被存储在代理服务器中,确保消息的可靠性传递。
  • 客户端离线时的所有QoS 1 和 QoS 2级别消息: 客户端离线时,当QoS 1 或者 QoS 2级别消息被发送到订阅主题时,代理服务器会存储这些被客户端错失的消息,防止丢失任何重要的信息。
  • 等待客户端收到QoS 2级别消息的完整确认消息: 由于客户端发送了QoS 2级别消息,代理服务器会一直监测它们的ACK状态。如果这些消息没有对应的完整ACK消息,代理服务器会一直等待这些消息的ACK被收到。

MQTT中的清除会话是什么意思?如何用清除会话来开启或者终止一个持久化会话?

当准备和代理服务器建立一个连接时,客户端可以通过设置cleanSession标志的值来启用或者关闭一个持久化会话。它的工作原理: 当cleanSession标志值为true时, 代表客户端明确请求的是一次非持久化会话。在这种场景下,如果客户端与代理服务器断开,来自先前持久化会话队列中的所有信息和消息都会被废弃。当客户端重新连接时,相当于是一次非常纯净的状态。

相反,当cleanSession标志值为false时, 代理服务器会为客户端创建一个持久化会话。这意味着在客户端离线时,代理服务器会保护所有与该客户端相关的所有信息和消息。会话会一直保留不变,除非客户端新请求一个纯净的会话。如果cleanSession标志设置为false,并且代理服务器已经有一个可用于客户端的会话,那么它将利用现有的会话,并在重新连接时将任何以前排队的消息传递给客户端。

有关在客户机和代理之间建立连接的更详细信息,请参阅我们的文章【译文】简述“MQTT客户端,MQTT代理服务器,MQTT连接”-MQTT基础:第三部分

客户端如何知道存在一个被存储的会话呢?

在MQTT版本3.1.1及更高版本中,代理服务器为响应客户端的连接请求而发送的CONNACK消息包含一个会话当前标志。此标志用作客户端的指示器,通知它以前建立的会话是否仍然可用于代理服务器。通过检查会话当前标志,客户端可以确定是建立新会话还是重新连接到先前的会话。为了全面了解连接建立过程,我们建议参考MQTT基础课程第3部分

客户端侧的持久化会话: 确保本地消息持久化和已确认的

除了客户端存储持久化会话,每个客户端在维护持续会话中也起着作用。当客户端请求服务器为会话数据时,服务器有责任并且必须存储下边的信息:

  • 代理服务器尚未确定的QoS 1 或 QoS 2的所有消息流: 客户端会跟踪它发送给代理服务器的QoS 1 或 QoS2级别消息。这些消息存储在本地,直到代理服务器确认了消息已收到或完成了,客户端才可以删除本地消息。如果消息需要完成预期可靠性的传输,客户端通过维护这些未经确认的消息,确保消息可以被再次重传。
  • 收到代理服务器的QoS 2级别消息需要等待完全被确认: 当代理服务器向客户端发送QoS 2级别消息时,消息会由客户端接收并处理。然而,在客户端确认成功的处理了这些消息之前,客户端会将它们一直存储在本地。这确保了客户端能在发生任何中断或连接断开时,依然保持消息传递的可靠性和完整性。
  • 通过在客户端存储这些与消息相关的详细信息,MQTT客户端可以积极地维护会话持久性,并确保在具有挑战性的网络条件下也能成功地处理消息。

MQTT会话管理最佳实践: 提高消息传递可靠性和资源使用效率

在使用MQTT时,必须考虑会话管理的最佳实践,以优化您的实现。以下是一些指导,帮助您确定何时使用持久会话或纯净会话:

MQTT持久化会话最佳实践

  • 确保消息的可靠性: 如果你的客户端需要接收一个特定主题的所有消息,甚至在客户端发生离线的情况也可以保证接收消息,那么持久化会话是一种合适的实现方式。这种方式可以确保代理服务器当客户重新连接时迅速把消息传递给它。
  • 资源优化: 如果你的客户端有资源限制,利用持久化是有好处的。在代理服务器上存储客户端订阅信息,有助于快速恢复中断的通信,减轻受限客户端的负担。
  • 继续发布: 如果您的客户端需要在重新连接后恢复发布QoS 1和 QoS 2消息,则需要持久化会话。代理服务器在客户端离线状态下一直保留这些消息,以确保它们的可靠传递。

纯净会话的最佳实践

  • 仅仅可以发布主题的客户端: 如果客户端只需要发布消息而不需要对主题进行订阅,则适合使用纯净会话。在这种情况下,代理服务器不需要存储会话信息或尝试传输QoS 1 或 QoS 2级别的消息,从而简化了会话管理过程。
  • 避免检索离线消息: 如果您的客户端不需要在脱机时接收错过的消息,则纯净会话就足够了。它消除了存储和传递客户端在脱机期间没有订阅的消息的开销。

MQTT 消息存储时长: MQTT代理可以存储多久的消息?

人们时常询问代理服务器存储会话信息和消息的时间。这个答案依赖于多种因子和考虑条件:

  • 内存受限: 通常,对消息存储的主要约束是代理服务器的操作系统对内存的限制。监测和分配足够的资源来处理预期的消息量是至关重要的。
  • 特殊场景: 管理消息存储持续时间的适当解决方案根据场景的不同而有所不同。要考虑诸如保留消息的重要性、消息过期策略以及法规或合规需求。

通过遵循这些最佳实践并考虑上述因素,可以有效地管理MQTT会话,优化消息持久性,并确保在基于你的MQTT解决方案中进行可靠的通信。

请记住根据您的独特需求和应用程序需求将这些准则合并到您的实现中。

总结

总而言之,为了理解和有效地利用持久化会话、队列机制和适当的会话管理实践,我们可以充分利用 MQTT 的潜力,构建健壮、可伸缩和可靠的物联网和消息传递应用程序。