MQTT协议基础

622 阅读8分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情

前言

        MQTT 协议由 IBM 和 Arcom 于 1999 年发明。当时是为了在狭窄的网络带宽和微小电力损耗的需求前提之下,实现石油管道传感器和人造卫星之间的通信。需要一个轻量、可靠的二进制通讯协议,这个通讯协议设计之初就需要解决工业通信领域的三大问题:

  • 网络带宽敏感、网络环境复杂不可靠。
  • 设备资源有限,内存容量小、处理器能力有限。
  • 设备对低功耗有要求。

        2011年11月,IBM和Eurotech将 MQTT 协议捐赠给Eclipse基金会。2014年10月,MQTT 正式成为一个开放的 OASIS 国际标准。如今 MQTT 经过不断的发展,已经成为了物联网 IoT 所必备的一种消息探测协议。目前广泛应用于 IoT 即物联网上,一些工业级别的应用场景,比如汽车、制造、石油、天然气等,非常适合当今资源有限的设备。

        本文主要针对MQTT相关的概念做科普,后续文章会详细介绍如何应用mqtt,以及客户端应用代码的编写。

基础概念

MQTT特性

        MQTT协议全称 Message Queuing Telemetry Transport,消息队列传输探测。具有以下特点:

  • 轻量可靠:MQTT 报文格式精简、紧凑,意味着网络传输的开销更小,可在严重受限的硬件设备和低带宽、高延迟的网络上实现稳定传输。
  • 发布/订阅模式(Pub/Sub):发布/订阅模式的优点在于发布者与订阅者的解耦,实现异步协议,即订阅者与发布者不需要建立直接连接、也不需要同时在线。
  • 为物联网而生:提供心跳机制、遗嘱消息、QoS 质量等级 + 离线消息、主题和安全管理等全面的物联网应用特性。
  • 生态完善:实现覆盖全语言平台的客户端和 SDK,已成为 AWS IoT Core、Azure IoT Hub 等众多云厂商物联网平台的标准通信协议。

与消息队列的区别

        看mqtt这种发布订阅的模式,和消息队列很像,也总会习惯性的将mqtt归类于消息队列,但其实还是有很大区别的。

  • 消息队列模式中,不存在消息没有客户端消费的情况,但是在 MQTT 中,存在 topic 无 subscriber 订阅的情况。

  • 消息队列模式中,一条消息只能被一个客户端所消费,负载会分布在队列的每个消费者之间;而在 MQTT 中,每个订阅者都会收到消息,每个订阅者有相同的负载。

  • 在传统的消息队列模式中,必须使用单独的命令来显式创建队列,只有队列创建后,才可以生产或者消费消息;而在 MQTT 中,topic 比较灵活,可以即时创建。

相关概念

Publish / Subscribe

        接触过消息中间件,应该都知道发布 - 订阅模式,传统的CS架构是 客户端 直接和 服务器 进行通信。发布订阅模式则是将消息的发布者 publisher与消息的订阅者 subscribers进行分离,二者之间并不会直接通信,甚至都不清楚对方是否存在,他们之间的交流由第三方组件 broker 代理。

image.png

        MQTT客户端包括发布者和订阅者,可以是运行 MQTT 库的任何设备或应用程序,它们仅与 MQTT broker通信,当设备(或客户端)想要将数据发送到服务器(或代理)时,它被称为发布。当操作被反转时,它被称为订阅,在发布/订阅模型下,如上图所示,多个客户端可以连接到broker并订阅相应的主题。

  • 如果订阅客户端到broker的连接断开,那么代理将缓冲消息,并在用户重联时将其推送给订阅者。
  • 如果发布客户端到broker的连接在没有通知的情况下断开连接,那么代理可以关闭连接并向订阅者发送包含发布者指令的缓存消息。

        发布/订阅模式消除了传统客户-服务器之间的直接通信,把通信这个操作交给了 broker 进行代理,实现了客户端和服务器之间的解藕。

Broker

        Broker 是任何发布/订阅机构的核心,充当发送消息的客户端和接收这些消息的订阅者的中转站。具有以下作用:

  • 负责接收所有消息,过滤消息,确定是哪个 client 订阅了每条消息,并将消息发送给对应的 client。
  • 负责保存会话数据,这些数据包括订阅的和错过的消息。
  • 负责客户端的身份验证和授权。

broker 的消息过滤有几个可选项:

  • 基于主题过滤:MQTT的每条消息都会有一个 topic,客户端订阅后,broker将消息发送到对应的topic中,确保客户端收到发布到 topic 中的消息。
  • 基于内容过滤:在基于内容的过滤中,broker 会根据特定的内容过滤消息,订阅客户端会过滤他们感兴趣的内容。这种方法的一个显著的缺点就是必须事先知道消息的内容,不能加密或者轻易修改。
  • 基于类型过滤:在使用面向对象的语言时,基于消息(事件)的类型过滤是一种比较常见的过滤方式。

        根据实现的不同,代理可以处理多达数百万连接的 MQTT client。因此在选择 MQTT 代理时,也需要考虑各方面因素,目前使用的mqtt broker有很多,关于broker的选型和各个broker的性能测试,可以参考这篇 测试报告

Messages

        当 MQTT client 在连接到 broker 之后就可以发送消息了,每条消息还会包含一个负载(Payload),Payload 中包含要以字节形式发送的数据。MQTT 是数据无关性的,也就是说数据是由发布者 - publisher 决定要发送的是 XML 、JSON 还是二进制数据、文本数据。MQTT 中的 PUBLISH 消息结构如下所示:

image.png

  • Packet Identifier:这个 PacketId 标识在 client 和 broker 之间唯一的消息标识。packetId 仅与大于零的 Qos 级别相关。
  • TopicName:主题名称是一个简单的字符串,/ 代表着分层结构。
  • Qos:这个数字表示的是服务质量水平,服务质量水平有三个等级:0、1 和 2,服务级别决定了消息到达 client 或者 broker 的保证类型,来决定消息是否丢失。
  • RetainFlag:这个标志表示 broker 将最近收到的一条 RETAIN 标志位为true的消息保存在服务器端(内存或者文件)。
  • Payload:这个是每条消息的实际内容。MQTT 是数据无关性的。可以发送任何文本、图像、加密数据以及二进制数据。
  • Dupflag:这个标志表示该消息是重复的,由于预期的 client 或者 broker 没有确认所以重新发送了一次。这个标志仅仅与 Qos 大于 0 相关。

        当 client 向 broker 发送消息时,broker 会读取消息,根据 Qos 的级别进行消息确认,然后处理消息。处理消息其实就是确定哪些 subscriber 订阅了 topic 并将消息发送给他们。

image.png

        最初发布消息的 client 只关心将 PUBLISH 消息发送给 broker,一旦 broker 收到 PUBLISH 消息,broker 就有责任将其传递给所有 subscriber。发布消息的 client 不会知道是否有人对发布的消息感兴趣,同时也不知道多少 client 从 broker 收到了消息。

总结

mqtt优缺点

MQTT 协议架构的轻量级特性和最小开销有助于确保低带宽的平稳数据传输,并减少 CPU 和 RAM 上的负载。MQTT 的优势包括:

  • 由于数据包最小化,网络传输开销小,能达到快速高效的数据传输。
  • 发布订阅多对多的机制,有效分发数据。
  • 可以直接实施遥感和控制。
  • 使用很小的功率,优化网络带宽,对资源有限的设备很友好。

但是MQTT 的也存在一些缺陷,包括:

  • 与CoAP协议相比,MQTT 的传输周期较慢
  • MQTT 的资源发现适用于灵活的主题订阅,而 CoAP 使用稳定的资源发现系统。mqtt的主题树只会越来越庞大
  • MQTT 是未加密的。只能使用TLS / SSL进行安全加密,但是SSL/TLS 不是轻量级协议。
  • 创建全局可扩展的 MQTT 网络非常困难。
  • 安全性、互操作性和身份验证还有待提高。因为消息接收方无法知道原始消息的发送者.