1、MQTT简介

1、MQTT简介

  MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅(publish/subscribe)模式的"轻量级"通讯协议。

  它工作在 TCP/IP协议族上,属于应用层协议,由IBM在1999年发布,如今已经成为OASIS规范。是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议,为此,它需要一个消息中间件 。

  MQTT最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。作为一种低开销、低带宽、低功耗占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。

  MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其中,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。

  MQTT 最初由 IBM 于上世纪 90 年代晚期发明和开发。它最初的用途是将石油管道上的传感器与卫星相链接。顾名思义,它是一种支持在各方之间异步通信的消息协议异步消息协议在空间和时间上将消息发送者与接收者分离,因此可以在不可靠的网络环境中进行扩展。虽然叫做消息队列遥测传输,但它与消息队列毫无关系,而是使用了一个发布和订阅的模型。在 2014 年末,它正式成为了一种 OASIS 开放标准,而且在一些流行的编程语言中受到支持(通过使用多种开源实现)。

  MQTT在IoT、internet of things、物联网等方面应用较多。MQTT(Message Queuing Telemetry Transport),是一个物联网传输协议,它被设计用于轻量级的发布/订阅式消息传输,旨在为低带宽和不稳定的网络环境中的物联网设备提供可靠的网络服务。MQTT是专门针对物联网开发的轻量级传输协议。MQTT协议针对低带宽网络,低计算能力的设备,做了特殊的优化,使得其能适应各种物联网应用场景。本文旨在研究其在消息发布/订阅/接收场景下的应用.

  物联网 (IoT) 设备必须连接互联网,通过连接到互联网,设备就能相互协作,以及与后端服务协同工作。互联网的基础网络协议是 TCP/IP,MQTT(消息队列遥测传输) 是基于 TCP/IP 协议栈而构建的,它已经成为 IoT 通信的标准。

  物联网(Internet of Things,IoT)最近曝光率越来越高。虽然HTTP是网页的事实标准,不过机器之间(Machine-to-Machine,M2M)的大规模沟通需要不同的模式:之前的请求/回答(Request/Response)模式不再合适,取而代之的是发布/订阅(Publish/Subscribe)模式。这就是轻量级、可扩展的MQTT(Message Queuing Telemetry Transport)可以施展拳脚的舞台。

  MQTT协议是针对如下情况设计的:

  (1)M2M(Machine to Machine) communication,机器端到端通信,比如传感器之间的数据通讯

  (2)因为是Machine to Machine,需要考虑:

  • Machine,或者叫设备,比如温度传感器,硬件能力很弱,协议要考虑尽量小的资源消耗,比如计算能力和存储等
  • M2M可能是无线连接,网络不稳定,带宽也比较小

 

  该协议的可用性取决于该协议的使用环境。IBM公司在2013年就向结构化资讯标准促进组织提交了 MQTT 3.1 版规范,并附有相关章程,以确保只能对规范进行少量更改。MQTT-SN是针对非 TCP/IP 网络上的嵌入式设备主要协议的变种,与此类似的还有ZigBee协议。

  纵观行业的发展历程,“MQTT”中的“MQ” 是来自于IBM的MQ系列消息队列产品线。然而通常队列本身不需要作为标准功能来支持。

  可选协议包含了高级消息队列协议,面向文本的消息传递协议,互联网工程任务组约束应用协议,可扩展消息与存在协议,数据分发服务,OPC UA以及web 应用程序消息传递协议。

2、MQTT特点

  MQTT协议是为大量计算能力有限,且工作在低带宽、不可靠的网络的远程传感器和控制设备通讯而设计的协议,它具有以下主要的几项特性:

  (1)使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合;
  (2)对负载内容屏蔽的消息传输;
  (3)使用 TCP/IP 提供网络连接;
  (4)有三种消息发布服务质量(Qos):
      “至多一次”,消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。这一种方式主要普通APP的推送,倘若你的智能设备在消息推送时未联网,推送过去没收到,再次联网也就 收不到了。
      “至少一次”,确保消息到达,但消息重复可能会发生。
      “只有一次”,确保消息到达一次。在一些要求比较严格的计费系统中,可以使用此级别。在计费系统中,消息重复或丢失会导致不正确的结果。这种最高质量的消息发布服务还可以用于即时通讯类的APP的推送,确保用户收到且只会收到一次。
  (5)小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量;这就是为什么在介绍里说它非常适合"在物联网领域,传感器与服务器的通信,信息的收集",要知道嵌入式设备的运算能力和带宽都相对薄弱,使用这种协议来传递消息再适合不过了。
  (6)使用 Last Will 和 Testament 特性通知有关各方客户端异常中断的机制。
      Last Will:即遗言机制,用于通知同一主题下的其他设备发送遗言的设备已经断开了连接。
      Testament:遗嘱机制,功能类似于Last Will。

  2.1、异步发布/订阅实现

  发布/订阅模式解耦了发布消息的客户(发布者)与订阅消息的客户(订阅者)之间的关系,这意味着发布者和订阅者之间并不需要直接建立联系。 

  这个模式有以下好处:

  • 发布者与订阅者只需要知道同一个消息代理即可;
  • 发布者和订阅者不需要直接交互;
  • 发布者和订阅者不需要同时在线。

  由于采用了发布/订阅实现,MQTT可以双向通信。也就是说MQTT支持服务端反向控制设备,设备可以订阅某个主题,然后发布者对该主题发布消息,设备收到消息后即可进行一系列操作。

  2.2、二进制格式实现

  MQTT基于二进制实现而不是字符串,比如HTTP和XMPP都是基于字符串实现。由于HTTP和XMPP拥有冗长的协议头部,而MQTT固定报文头仅有两字节,所以相比其他协议,发送一条消息最省流量。

  2.3、一个设备完全可以同时充当发布者和订阅者,并且可以发布和订阅多个不同的主题

  这不仅是MQTT协议支持的功能,更是物联网设备实现复杂交互的标准模式。一个设备可以同时执行以下操作:
    发布 到多个主题(例如:上报状态、上报数据、上报错误)
    订阅 多个主题(例如:接收控制命令、接收配置更新、接收广播消息)

  为什么一个设备需要订阅多个主题?
  设备订阅多个主题通常是为了接收不同类型的信息或指令,实现功能的解耦。下图以一个典型的智能家居设备为例,展示了多订阅的工作模式:

image

  让我们通过一个智能家居中智能灯具的典型示例,来理解这种多主题发布/订阅模式是如何工作的:

image

  实际应用场景
  场景:工业网关设备
  发布数据:
    向 gateway/{id}/sensor/data 主题发布从各个传感器收集的数据
    向 gateway/{id}/status 主题发布自身的状态信息(在线、离线、心跳)
    向 gateway/{id}/alerts 主题发布报警信息
  订阅命令:
    订阅 gateway/{id}/command 主题,接收来自服务器的控制指令(如重启、重置)
    订阅 gateway/{id}/config/update 主题,接收配置更新信息
    订阅 system/broadcast 主题,接收系统级的广播通知

  优势总结
  这种模式的强大之处在于:
    功能完备:设备既能上报数据,也能接收指令,实现双向通信。
    职责分离:不同的主题用于不同的目的,使系统逻辑清晰,易于维护和调试。
    高度灵活:可以轻松扩展设备的功能,只需增加新的发布或订阅主题即可。
    系统集成:设备可以轻松地与系统中的多个其他组件交互。
  注意事项
    主题规划:良好的主题命名规范非常重要,避免主题混乱。
    消息处理:在设备端需要妥善处理来自不同主题的消息,确保不会因为处理某个消息而阻塞其他消息。
    资源管理:对于资源受限的嵌入式设备,需要确保同时处理多个主题的发布和订阅不会耗尽内存或网络带宽。
  结论:一个设备同时发布和订阅多个MQTT主题不仅是可行的,而且是构建功能完整的物联网设备的标准做法。

  2.4、订阅和发布主题的创建

  MQTT的主题不需要在服务器上提前创建或注册。这是一个非常关键的特性,它使得MQTT协议极其灵活和易于扩展。主题是一个动态的、运行时的概念。
  工作原理
  发布时自动“创建”:
    当第一个客户端向一个不存在的主题发布消息时,MQTT Broker会在内存中即时地建立这个主题的路由信息。
    这个过程对客户端是透明的,你不需要任何特殊的API或配置。
  订阅时建立映射:
    当客户端订阅某个主题(或通配符)时,Broker会记录下这个“客户端-主题过滤器”的映射关系。
    同样,不需要提前创建主题。
  消息路由:
    当一条消息发布到Broker时,Broker会将其主题与所有已记录的订阅进行匹配。
    匹配成功后,消息就会被转发给对应的客户端。
  自动清理:
    如果某个主题不再有任何订阅者,并且没有保留消息,Broker通常会为了节省资源而清理掉该主题的相关路由信息。当下一次有发布或订阅时,它会再次被动态创建。

  正因为主题不需要创建,如果管理不当,也会带来问题:
  主题拼写错误:
    这是最常见的错误。如果你不小心把 sensor/temperature 拼写成 sensor/temperatur,Broker不会报错,它会认为这是一个全新的主题。订阅者将收不到消息,而你可能要花很长时间来调试这个“神秘”的丢失消息问题。
  主题泛滥:
    如果设备使用唯一的标识符(如设备序列号)作为主题的一部分(例如 data/device/SN12345/status),并且有数百万台设备,那么Broker内存中可能会维护数百万个主题的路由条目。虽然成熟的Broker(如EMQX, HiveMQ)能处理,但这确实对服务器资源提出了要求。
  安全风险:
    因为任何客户端都可以向任何主题发布或订阅,如果权限控制不当,一个恶意的客户端可能会向一个关键主题发布垃圾信息,或者窃听敏感主题。因此,配置强大的认证和授权是至关重要的。

   2.5、发布的主题消息没有客户端订阅,那发布的消息去哪了

  发布的数据去到了MQTT服务器(Broker),如果有订阅者那么就由Broker根据主题(Topic)将其分发给了所有订阅了该主题的客户端,如果没有订阅者。
  下面我们来详细分解这个过程:
  假设你有三个角色:
    MQTT Broker(服务器): 消息的中枢,负责接收所有消息并分发给符合条件的客户端。
    你的客户端(Publisher Only): 只发布,不订阅。
    其他客户端(Subscriber): 订阅了特定主题,用来接收消息。
  整个数据流向如下图所示:

image

  让我们来一步步解读图中展示的流程:
  (1)发布(Publish)
    你的客户端建立一个到MQTT Broker的连接。
    你的客户端向Broker发送一条PUBLISH数据包,这个数据包中包含两个关键信息:
      主题(Topic): 例如 sensor/temperature。
      有效载荷(Payload): 你要发送的实际数据,例如 "25.6"。
  (2)Broker 接收与处理(Receive & Process)
    Broker收到你的PUBLISH数据包。
    Broker会检查这条消息的主题(Topic)。
    Broker在其内部的订阅列表中查找:当前有哪些客户端订阅了这个 sensor/temperature 主题?
  (3)路由与分发(Route & Distribute)
    情况一:有订阅者
      如果Broker发现有一个或多个客户端(比如一个手机App或一个服务器应用)订阅了 sensor/temperature,那么Broker会立即将这条消息(包含主题和载荷)转发给每一个在线的订阅者。
      如果你的消息设置了保留标志(Retained Flag),Broker还会将这条消息保存下来。之后任何新订阅 sensor/temperature 的客户端,都会立刻收到这最后一条保留消息。
    情况二:无订阅者
      如果Broker检查后发现,当前没有任何客户端订阅了 sensor/temperature 这个主题,那么它会简单地丢弃这条消息。
      唯一的例外是,如果这条消息设置了保留标志(Retained Flag),Broker会丢弃消息本身,但会保留其主题和载荷。当有新的订阅者出现时,这条保留消息会被发送。

      一个重要的例外:保留消息
      如果发布者在发送数据时,将报文中的 “保留消息”标志位设置为 true,那么情况就完全不同了。
      Broker的行为:
        Broker仍然会检查当前是否有订阅者。如果没有,它不会将消息转发给任何人。
        但是,Broker会在内部存储这条消息。它会将最后一条携带保留标志的、针对某个特定主题的消息保存起来。
      后续的影响:
        之后,任何新的客户端只要订阅了 sensor/temperature 这个主题,Broker会立即将这条保存的保留消息发送给它。
        这样,新订阅者就能立刻获取到最新的状态值,而不必等待下一条数据发布。
      保留消息的比喻:
        这就像是在公告栏上贴一张通知。即使贴的时候没人看,通知也会一直留在那里。后来的人只要走到公告栏前(订阅主题),就能立刻看到这份通知。
      QoS等级的影响
        QoS(服务质量)等级主要影响消息在传输过程中的可靠性,但它不会改变“无订阅者则消息被丢弃”这个根本规则。
        QoS 0: 消息最多发送一次,可能丢失。在无订阅者场景下,消息就是丢失了。
        QoS 1: 发布者会确保Broker收到消息。Broker收到后会回复一个PUBACK,然后再丢弃消息。对发布者来说,它认为消息已成功送达Broker,但实际上Broker已经将其丢弃。
        QoS 2: 发布者会确保Broker恰好收到一次消息。流程最复杂,但最终Broker在确认收到后,依然会丢弃消息。
        总结:QoS保证的是消息从发布者到Broker的传输,而不是从Broker到订阅者的传输。

3、设计规范

  由于物联网的环境是非常特别的,所以MQTT遵循以下设计原则:

  (1)精简,不添加可有可无的功能;
  (2)发布/订阅(Pub/Sub)模式,方便消息在传感器之间传递;
  (3)允许用户动态创建主题,零运维成本;
  (4)把传输量降到最低以提高传输效率;
  (5)把低带宽、高延迟、不稳定的网络等因素考虑在内;
  (6)支持连续的会话控制;
  (7)理解客户端计算能力可能很低;
  (8)提供服务质量管理;
  (9)假设数据不可知,不强求传输数据的类型与格式,保持灵活性。

转自:https://www.runoob.com/w3cnote/mqtt-intro.html    

posted @ 2020-08-12 11:44  孤情剑客  阅读(1192)  评论(0)    收藏  举报