于1999年面市的MQTT,最初被用于油气管道与远程卫星之间的通信。目前它作为一种工具,被广泛地用在各种规模的部署中,以连接多种类型的物联网(IoT)设备。由于是基于TCP/IP的网络协议,因此MQTT采用的是发布方-订阅方(publisher-subscriber)的通信模型。它的轻量级特性足以让其运行在IoT设备上,而其强大的功能又确保了它能够在不稳定的网络条件下工作。
MQTT的工作原理
MQTT协议是由如下元素构成:
发布方(Publisher):设备通过主题将消息发送给订阅方。
主题(Topic):每个资源都有一个唯一的标识符。发布方将消息发送至主题,然后将其传递给订阅方。
订阅方(Subscriber):作为终端设备,订阅方通过主题从发布方处接收消息。
代理(Broker):服务器作为中央枢纽,负责发布方和订阅方之间的组织级通信。
下图展示了简单的MQTT通信逻辑。
如果某个云平台不适合使用MQTT的通信方式来开发系统,则可以改用hbmqtt、gmqtt和paho-mqtt lib。
服务质量级别(QoS)是MQTT协议的关键功能,作为消息发送方和接收方之间的约定,它定义了系统传递特定消息的能力。
客户端可以选择与其所处网络的可靠性,以及应用程序的逻辑,相匹配的服务级别。由于MQTT能够通过重新传输的机制,来管理并保证消息的传递(即使是底层的传输并不可靠),因此QoS可以让不可靠网络中的通信更加安全。
为何在物联网的开发中要用到MQTT?
凭借其“节能(energy-efficient)”的数据传输方式,MQTT往往被用在CPU和内存(RAM)功率有限的低功耗设备上,以及如下场景用例中:
高效的通信。MQTT的低数据量和低能耗特性,使其成为实时的、基于文本的消息传递应用的首选。
安全性。在家庭安防系统中,MQTT系统的QoS机制可以确保重要消息的成功传递,进而确保危险警告能够发送给居民。
消息汇总。MQTT使得组织能够有效地,从诸如智能手机或汽车传感器等多个来源收集数据。
同步传感器。例如,多个火灾报警探测器可以相互通信,以辨别危险是否真的存在。
医疗物联网应用。通过多个传感器去监控出院患者的健康参数。
车联网。与HTTP不同,MQTT能够在客户端和代理之间保持持久性的会话。该特性对于车联网特别实用。例如,当车辆离开了蜂窝网络的盲区,会话能够重新连接,继续平稳地收发数据,而无需进行复杂的HTTP握手。
MQTT的优势
效率是MQTT的一大亮点,它通过诸如AMQP的竞争协议,让数据的传输更加顺畅。用户可以快速、轻松地实现轻量级的MQTT协议架构。
发送的数据包越少,网络的使用率就越低。
其低功耗特性非常适合连接物联网设备。
MQTT可以实现更有效的数据分发。
该协议可以更轻松地实现遥感(remote sensing)和控制。
MQTT的劣势
当然,MQTT并非在所有场景中都是理想选择。MQTT协议在客观上存在着如下劣势:
对于拥有250个以上设备的系统而言,快速传输周期是至关重要的。不过它与CoAP(Constrained Application Protocol)相比,会在传输周期上慢一些。
MQTT可以运行在灵活的主题订阅系统上。而CoAP使用的是稳定的资源发现系统。
MQTT虽然用到了TLS/SSL,可是它缺乏安全加密能力。
与其他竞品相比,MQTT协议难以创建全局性的可扩展网络。
MQTT v5.0的功能概述
通过各种新功能,MQTT v5.0可以实现如下目标:
提高大型系统的性能。MQTT v5.0以一种适当的架构,简化并协调上万台设备之间的通信。
错误报告。MQTT v5.0协议将返回码重命名为原因码(reason code),以指示更多类型的错误。
实现常规交互。MQTT v5.0规范化了设备间交互的重复方式,并定义了它们如何响应请求的能力。
增加了可扩展的机制。MQTT v5.0新的功能包括:添加自定义的属性,指定内容的类型或负载的格式。
更好的支持。特别是对于希望通过MQTT来提高生产率的小型用户而言,能够从中受益。
MQTT v5.0与MQTT 3.1.1的基本功能
1.通信功能
可以通过负载内部的身份验证方法,以及身份验证类数据的属性,来实现增强的身份验证。
可以使用“会话过期间隔”属性。例如,可以在主题内包括订阅的时间,消息会被存储的时限等。
可以内置化地限制客户端和服务器端的最大数据包的体积(待传输的字节数)和最大接收量(客户端或服务器同时发送消息的数量)。
通过“待延迟的间隔”属性,实现对消息的延迟发送。
“服务器参考”或“服务器重定向”属性,可以协助将数据包传输到不同的代理或服务器处。
2.发布功能
消息到期间隔,可用于设置消息的保留期限。
负载格式标识符和内容类型属性,可被定义为二进制字节、UTF-8或MIME类型。
支持主题别名。例如,通过将topic/v1/device/赋予别名“1”,可以最大程度地减少所需的数据包的数量。
MQTT协议的“响应主题”,类似HTTP协议的响应请求方案(response-request scheme)。
3.订阅功能
非本地发布,可以让用户选择不接收客户端发布的消息。
留存消息控制可以控制消息的排序。
订阅标识符,可用于在订阅中识别服务器。
共享订阅,可通过其他标志和过滤功能,来实现更灵活的订阅。
4.一般特征
在MQTT v3.1.1中,服务器无法提供有关在建立通信、发布消息、以及订阅主题等不同阶段的问题与错误原因。但是,v5.0可以提供所有ACK消息的原因码。
与MQTT 3.1不同,在MQTT v5.0中,客户端和服务器端可以彼此传递有关掉线信息的数据包。
不同的用户属性可以被存储在各种键值中。
MQTT v5.0在小型系统部署中的示例
下面让我们来看一个带有基于Python的客户端利用MQTT v5.0本地网络的示例。在客观总结其优缺点的同时,我们还会将其与MQTT v3.1.1的网络进行比较。
场景简述
假设有一栋实现了局域网(LAN)覆盖的建筑物。其中某些房间被安装了三种设备--独立的运动传感器、照相传感器和音频传感器。其主机设备位于LAN之中,并通过无线或网线的方式连接到路由器上。它能够定期从独立的设备上收集或处理数据,并且将这些数据存储在本地数据库中。目前,我们使用SQLLite数据库或更简单的替代方法,仅在收到三种传感器的消息后,才会被激活工作。
目标
保证主机设备与独立设备之间的通信,并在主机端提供本地数据库的部署和通信。
应用要求
从传感器到主机设备的所有消息,都必须遵从MQTT v5.0附加属性的限制(包括:传输给主题消息的字节数限制等)。
来自主题的消息必须是MIME类型,以便于在主机端进行快速编码。
消息必须存储在本地数据库的实例中。
设备要求
独立设备:带有已连接的传感器,而且能够访问本地网络的x86或基于ARM的设备(如,Raspberry Pi)。
主机设备:具有MQTT代理、且能够处理来自独立设备消息的基于x86或基于ARM的设备。
支持MQTT v5.0和Python的代理
虽然paho-mqtt是两种常见的代理。但是,由于它们并无内置的MQTT v5.0代理,因此无法实现网络的本地部署。对此,我们采用支持MQTT v5.0的Mosquitto作为代理。其配套的文档链接为--https://mosquitto.org/。它能够代理大约200到300个设备,且一次性仅支持一个连接。
基于Python的系统如何与MQTT v5.0一起使用
在Python开发人员看来,MQTT v5.0协议里的库和文档并不多。其唯一的Python 客户端便是上面提到的gmqtt和paho-mqtt。
MQTT v5.0本地网络的优缺点
优点
无需诸如GCP(Google Cloud Platform)或AWS之类的云服务提供商,也不需要用于本地IoT系统的WAN连接,便可实现LAN内自主设备的全面交互。
网络延迟和数据传输速度。传输速度仅取决于本地设备的硬件功能。在LAN环境中,通过放置设备可以最大程度地减少延迟。
与竞品相比,MQTT的能效更高。
网络安全性高。由于本地网络不会暴露到WAN中,因此带有消息的数据包不会被本地网络之外实体捕获或跟踪到。同时,MQTT v5.0协议提供了服务器与客户端之间的相互身份验证。此外,MQTT还可以使用TLS证书的安全连接和数据传输。
可以将数据包的各种限制,作用于网络内的代理上。
其容器化特征更易于模拟和调试。
缺点
用于处理消息的线程应当实现并行管理,以确保设备的正常运行。
开发人员必须定期进行调试和排障,并且必须使用安全的SSH,来保护主机和独立设备之间的WAN连接。
MQTT协议不支持流式传输。
由于无法实现大型的文件传输,因此需要专用的bucket上传或HTTP协议。
代理无法智能地管理数据。当然,在断开连接期间,数据可以被存储一段时间。
MQTT v5.0较v3.1.1的改进之处
存储附加数据的属性
载荷格式的指示符类型包括:字节、UTF-8或UTF-8字符串对
请求/响应模式
客户端连接和断开的原因码
会话到期与控制
MQTT v5.0可以简化数据负载的处理和解析,具有对消息、连接和会话进行单独且精确控制的能力。而且,它能够通过属性来传输附加数据,开发者可以据此创建更为复杂的IoT解决方案。
MQTT v5.0的挑战
在生产环境中,开发者需要管理那些用于在独立设备上,并行发布和侦听消息的进程与线程。
在paho-mqtt之类的代码包中,各种类的实现过程并不清晰,而且可参考的文档十分有限。
由于文档匮乏,因此开发者很难安装代理,并将其升级到MQTT v5.0。
为了识别网络中的设备,我们需要将IP发现器添加到系统中。
到底是否该选用MQTT v5.0?
总的说来,如果您拥有在设备与主机之间进行消息通信的托管式代理设备,而且物联网的规模不大,那么将MQTT v5.0用于本地IoT设备间的通信则为首选。