MQTT深入——物联网基础传输协议

可以预测,随着通讯技术日益发展,追随着互联网,移动互联网之后的互联网将是人类科技史上又一次重大变革,科技改变生活,物联网将全方位改变我们的生活。那么什么是物联网,万物如可联网呢?今天虫虫就给大家介绍万物联网基础协议MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),一种轻量级,开源和可访问的协议。

概述

MQTT是一种发布/订阅(publish/subscribe)式消息传递协议,其历史可追溯到上世纪末年1999,由Andy Stanford-Clark(IBM)和Arlen Nipper(Cirrus Link)的开发,用于在带宽有限、连接不可预测的网络上维持机器间通信的方法。最初用于保持石油管道的各个部分之间互相通迅,并通过使用卫星和管理中心通讯。

由于极其恶劣的通讯条件,使得协议非常轻量、代码占用空间极低,是低功耗设备和电池寿命有限的设备的理想选择,MQTT已成为有限CPU功率和电池容量有限设备之间流式传输数据的首选协议,适用于价格昂贵或低带宽,稳定性不可预测或高延迟的网络。所以MQTT天生适用物联网的通讯。

MQTT是构建在TCP/IP协议之上的,也有一个名为MQTT-SN的分支,用于蓝牙,UDP,ZigBee和其他非TCP/IP物联网链接。

MQTT不是同类中唯一的发布/订阅(publish/subscribe)实时消息传递协议,但它已经在各种依赖于机器到机器通信的环境中得到广泛采用。同时代消息传输西医还有WAMP (Web Application Messaging Protocol ,Web应用程序消息传输协议),STOMP(Streaming Text-Oriented Messaging Protocol,流式文本定向消息传输协议)和AMQP(Alternative Message Queueing Protocol,可选消息队列协议)。

MQTT工作原理

基于MQTT构建的通信系统由发布者,代理(MQTT服务器)和一个或多个客户端(订阅者、消费者)三部分组成。发布者不需要关心接收消息的订户的数量或位置等等配置。同样,消费者不需要特定的发布服务器的配置。系统上可以有多个代理分发消息。

MQTT提供了一种创建通信通道层次结构的方法。该方法有点像带有树状叶子的分支。每当发布者将新数据分发给客户时,消息中都附加发送控制备注。较高级别的客户端可以接收所有的消息,而较低级别的客户端只能接收与传递层次结构底部的一个或两个基本信道叶子的消息。这样可以传输小至2B大到256MB的信息。

一个MQTT客户端通过MQTT代理连接的示例:

由MQTT代理发布或接收的数据都将以二进制编码, MQTT是二进制协议:

MQTT代理有时可能会累积一些当前订户的通道无关的消息。这时会根据控制消息中的指令丢弃或保留消息。这样有新订户就可以直接获取最新记录的数据点,不需要等到下一次发送,这很有用。

需要说的是MQTT使用纯文本来传输用户凭据,也不提供对身份验证或安全功能的支持。所以需要用SSL来加密保护传输的信息不被拦截或篡改。

MQTT功能

MQTT具有以下的功能:

基于于消息内容的不可知;

适用于一对多通信分配和解耦应用;

具备"遗嘱"功能,通知各方客户异常断线;

出于基本连接目的,取决于TCP/IP;

至多一次,至少一次,和只发送一次三种消息质量QoS(消息传递次数)发布模式;

可以同时为发布者,消费者两种的角色。

MQTT还有一个显著特征是它对通道的利用。在MQTT中将每个通道都视为文件路径:

channel = "user/path/channel"

通道确保每个监听接收其订阅的消息。MQTT通过将通道视为文件路径来实现各种有用的通信功能,包括允许基于监听所在文件路径上订阅的位置或位置分支进行消息过滤。

MQTT消息传递格式

下面是使用MQTT协议消息都由两部分组成组成:

字节1:包含消息类型(客户端连接请求,订阅确认,ping请求等),复制标记,保留消息指令和有关服务质量等级(QoS)的信息。

字节2:包含有关消息剩余长度的信息,包括有效载荷和可选变量头中的任何数据。

QoS级别

字节1中的QoS标志值是MQTT支持的可变功能的核心。QoS标志包含基于消息的意图和紧急程度三种值:

0, 最多一次,服务器触发和忘记,消息可能丢失或重复。

1, 至少一次,收件人确认传递,消息可能重复,但确保传递到位。

2, 只发送一次,服务器确保交付,消息准确到达一次而不会丢失或重复

MQTT现状

今年年4月7日,OASIS正式发布了MQTT v5.0官方开源标准。OASIS组织是一个由600个成员组织和5000多人参与者组成的非营利性联盟。

5.0版引入了一些实时开发新功能。这些新功能向后兼容已部署的版本的MQTT。

这些新功能包括:

改进了错误报告:新版中无论出于何种原因,返回代码都可以在数据未成功传输时通知用户。支持可选的Reason字符串,有助于改进诊断和故障排除工作。

订阅共享:为了帮助平衡负载,可以在接收端的多个客户端之间共享订阅。

消息属性:5.0版引入了元数据作为消息头的一部分。它可以向最终用户传达附加信息,或者它可以促进下面包括的一些其他功能。

通道别名:发布者可以使用数字标识符替换通道,以减少需要传输的字节数。

消息到期:如果系统无法在预设的时间内提供消息,则可以将消息标记为自动删除。MQTT 5.0的新功能完整列表可以在官方标准的附录C中找到。

MQTT的使用

随着物联网应用程序不断发展完善,MQTT通过一种开放,直接和可扩展的方式将分布式计算和物联网功能推广到更广泛的用户群,包括在消费者和工业市场。

MQTT是一种轻量级消息传递协议,设计用于网络质量不确定和物理限制设备:电源和CPU。但是MQTT的使用并不仅限于此,可以广泛用于从重复数据采样到工业机器控制,可为许多物联网基础设施类型提供不同级别的服务。

除了当今市场上的消费级设备和服务外,MQTT还在各种大小规模的企业基础设施被应用,包括智能手机和平板电脑,能源监控系统,医疗设备,石油钻井平台和钻井现场,汽车和航空航天工业,以及材料处理,建筑,供应链,零售等中使用的传感器和机器视觉系统。

使用场景

环境传感器数据:MQTT支持"最多一次"消息传递模型。在覆盖范围不稳定或高延迟的网络上,信息可能会丢失或重复。远程传感器以设定的间隔记录和传输数据的领域新的读数定期擦剂,数据可丢失但是不能错误。远程环境中的传感器通常是低功耗设备,MQTT非常适合具有较低优先级数据传输需求的物联网传感器网络。

机器健康和告警数据:为了快速响应新出现的问题并避免停机,风力涡轮机可能需要向本地团队提供有保证的机器运行状况数据,甚至在信息到达数据中心之前。对于这样的需要,"至少一次"消息传递确保在正确的时间看到维护标志以防止问题,即使这些标志可以重复出现。适用于更高优先级的机器对机器通信系统。

计费系统:在更高优先级和更准确度的消息需求,比如涉及计费的地方,只发送一次QoS标签就派上用场了。这样可以消除计费或发票系统中重复或丢失的消息包,并减少异常情况,减少与客户的不必要冲突。

不适用场合

开发人员可以选择用于设计和部署双向物联网功能的协议,包括MQTT,HTTP,CoAP,WebSockets等。MQTT是否是最佳选择取决于你希望应用程序执行的操作以及硬件的性质。

MQTT专为极低带宽环境而设计,在保存每个字节的过程中可能很不灵活。例如,规范定义了五个错误响应,服务器可以使用这些错误响应拒绝连接(例如,错误的用户名或密码,或不可接受的协议版本);如果服务器扩展一些不属于这五个错误的错误,那就不行了。更糟糕的是,如果在连接运行后发生错误,则根本没有用于错误协议消息的机制,服务器不会发出任何回应,客户端不知道为什么被丢弃(没有方法可以区分故意断开与瞬态网络问题)。对于习惯于更灵活、更容易调试(尽管带宽节省更少)协议的人来说,这种对带宽的错误处理方式可能有点原始。

MQTT通常会和HTTP对比,谷歌组织开展了一项研究,比较两者的响应时间,数据传输大小和其他对开发人员重要的属性。MQT只有在连接可以重用以发送多个有效负荷时在测试中才获得比较好的效果。

HTTP和MQTT都是物联网应用的理想选择,因为它们具有相当紧凑的传输大小以及对设备电池寿命和内存的低要求。

CoAP是物联网开发常用的另一种协议。与MQTT相似,但有明显的差异。MQTT是一种多对多协议,而CoAP主要是用于服务器和客户端之间通信的一对一协议。CoAP还提供MQTT没有的元数据,发现和内容协商功能。

如果客户端只需要接收数据,那么SSE(Server-Sent Events)也是一个有效的选择。

MQTT快速构建

MQTT GitHub存储库(github/mqtt)包含各种语言的开源MQTT库的广泛列表。次数我们选择基于PHP,Python,JS,c#语言实例进行简单代码演示实现。

Eclipse Mosquitto

Eclipse Mosquitto是一个开源(EPL/EDL许可)消息代理,它实现了MQTT协议版本5.0,3.1.1和3.1。Mosquitto轻量级,有多种语言基于此的开发库,适用于从低功率单片机到服务器的所有设备。下面是一个php语言的Moquitto库是示例:

一个Moquitto Python语言库(Eclipse Paho Python)实例:

MQTT.js

MQTT.js是MQTT协议的JS语言客户端库,用于node.js和浏览器。下面是一个使用MQTT.js发送消息的示例:

MQTTnet

MQTTnet是一个用于基于MQTT的通信的高性能.NET库。它提供MQTT客户端和MQTT服务器(代理)。

设置MQTT客户端:

设置MQTT客户端选项后,可以建立连接。以下代码显示如何连接服务器:

显示收到的消息:

发布消息:

部署

在规模部署方面需要注意首先MQTT是一种网络协议,无论如何选择,都需要基础设施和网络功能来处理通过MQTT增加的设备到设备流。

轻量级机器对机器(LWM2M)是另一种在企业级别与MQTT一起使用协议。与MQTT相比,LWM2M有时更适合长期物联网的部署。当企业希望在没有大量购买的情况下参与物联网功能试运行时,MQTT是理想的选择,而LWM2M则为企业构建具有多功能性长期基础设施提供了功能。LWM2M具有卓越的设备管理工具,例如连接监控,固件更新和远程设备操控。对于拥有大量非托管设备向中央物联网平台发送大量数据的企业而言,LWM2M是更好的选择。

在服务器负载方面,服务器可以处理的并发连接数很少成为瓶颈。大多数的MQTT服务器/代理可以支持数千个并发连接,但是一旦MQTT服务器进程处理了实际数据的接收,处理和响应消息所需的工作量是多少?通常会出现各种潜在问题,例如读取和写入数据库,与服务器集成,为每个客户端分配和管理资源等等。一旦一台机器无法应对工作负载就需要增加服务器,这就需要负载平衡和集群设计,连接到不同服务器的客户端之间的消息同步等。

  • 发表于:
  • 原文链接:https://kuaibao.qq.com/s/20190805A09VRQ00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券