物联网的基石-mqtt 协议初识

云栖号资讯:【点击查看更多行业资讯】
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!


随着 5G 时代的来临,万物互联的伟大构想正在成为现实。联网的 物联网设备 在 2018m k ? _ $ D Pb K . +已经达到了 70 亿1,在未来两年,仅智能水电气表就将超过10亿2

海量的设备接入和设备管k b d } 理对网络带宽、通信协议以及平台服务架构都带来了很大挑战。对于 物联网协议 来说,必须针F y W对性地解决物联网设备通信l m K ) n m U 2的几个关键问题:其网络环境复杂而不可靠、其内存和闪存容量小、其处理器能力有限。

MQTT 协议 是基于发布/订阅模式的物联网通信协议,凭借简单易实现、支持 QoS、报文小等特点,占据了物联网协议的半壁江山:

物联网的基石-mqtt 协议初识

MQTT 协议的诞生

MQTT was created by Andy Stanford-Clark of IBM, aG n Mnd Arlen Nipper (then of Arcom Systems, laterP n r H CTO of Eurotech).^3

据 Arlen Nipper 在一 IBM Podcast 上的自述,MQTT 原名是 MQ TT, 注意 MQ 与 TT之间的空格,其全称为: MQ Telemetry Transport,是九十年代早期,他在参与 Conoco Phillips 公司的一个原油管道数据采集监控系统(pipeline SCADA system)时,开发的一个实时数据传输协! $ z U j m j议。它的目的在于让传感器通过带宽有限的 VSAT ,与 IBM 的 MQ Integrator 通信。由于 Nipper 是遥感和数据采集监控专业出身,所以按业内惯例给了个 MQ TT 的名字。

MQTT 协0 k | 5议设计原则

按照 Nipper 的介绍,MQTT 必须简单容易实现,必须支持 QoS(设备网络环境复杂),必S | ( f须轻量且省带宽(因为那时候带宽K S X w T ?很贵),必~ @ P须数据无关(不关心 Payload 数据格式),必须有持续地会话感知能力(时刻知道设备是否在线)。下面将介绍 MQTT (3.1.1 版本) 的几个核心特色,分别对应了这几个设计原则的实现。

灵活的发布订阅和主8 , e 9题设计

发布订阅模Z u b Y % h C j 1式是传统 Client/Server 模式的一种解耦方案。发布者通过 Broker 与消费者之间: O : n x X s :通信,Broker 的作用是将收到的X o + R % ! z消息通过某种过滤规则,正确地7 T }发送给消费者。发布/订阅模式 相对于 客户端/服务器模式 的好处在于:

  • 发布者和消费者之间不必预先知道对方的存在,比如不需要预先沟通对方的U C b 3 L IP Address 和 Port
  • 发布者和消费者之间不必同时运行。因为 Broker 是一直运行的。

在 MQTT 协+ u d F S x N c议里,上面提到的 过滤规则 是 Topic。比如:所有发布到 news 这个 Topic 的消息,都会被 Broker 转发给已经订阅了 news 的订阅者:

物联网的基石-mqtt 协议初识

上图中订阅者预先订阅了 news,然后发布者向 Broker 发布了一条消息 "some msg" 并指定发布到 news 主题,Broker 通过 Topic 匹配,决定将这条消息转发给订阅者。

MQTT 的 Topic 有层级结构,并且支持通配符 + 和 #:

1.+ 是匹配单层的通配符。比如 news/+ 可以匹配 news/sports,news/+/basketball 可匹配到 news/sports/basketball。

2.# 是? q 2一到多层的通配符。比如5 C z news/# 可以匹配 news、 news/sports、news/sports/basketball 以及 news/sports/basketball/x 等等。

MQTT 的* m 1主题是不要预先创建的,发布者发送消息到某个主题、或者订阅u Q | 1 6 p f者订阅某个主题的时候,Broker 就会自动创建这个主题。

带宽消耗最小化

MQ( N h 7 L {TT 协议将协议本身占用的额外消耗最小化,消息头部最小只需要占用 2 个字节。

MQTT 的消息格式N J 3分三部分:

  • 固定长度头部,2 个字节,所有消息类型里都有
  • 可变长度头部,只有某些消息类型里有
  • Payload,只有某些消息类型里有

MQTT 的主要消息类型有:

  • CONNECT / CONNACK
  • PUBLISH / PUBACK
  • SUBSCRIBE / SUB} 0 C q g C * q .ACK
  • UNSUBSCRIBE / UNSUBACS Q #K
  • PINGREQ / PINGRESP
  • DISCONNECT

其中 PINGREQ / PINGRESP 和 DI( k ]SCONNECT 报文是不需x a N 8要可变头部的,也没有 Payload,也就是说它们的报文大小仅仅消耗 2 个字节。

在 CONNECT 报文的可变长度头部里,有个 Protocol Ve) 2 w arsion 的字段。为了节省空间,只有一个字节。所以版本号不是按照字符串 "3.1.1" 存放的,而是使用数字 4 来表示 3.1.1 版本。

三个可选的 QoS 等级

为适应设备不同的网络环境,MQTT 设计了 3 个 QoS 等级w 1 b a T l,0, 1, 2:

  • At most once (0)
  • At least once (1)
  • Exactly once (2)

QoS 0 是一种 "fire and forget", Y t J ( W 的消息发送模式s } # U I:Sender (可能是~ q ) m n I 8 , Publisher 或者 Broker) 发送一条消息之后,就不再关心它有没有发送到对方,也不设置任何重发机制。

QoSg u x o Z g 1 包含了简单的重发机制,Sender 发送消息之后等待接收者的 ACK,如果没收到 ACK 则重新发送消息。这种q K @模式Y b W - : / y能保证消H r G l . i息至少能到达一次,但无法保证消息重复。

QoS 2 设计了略微复杂的重发和重复消息发现机制,保证消? X ^ j { H A 息到达对方并且严格值到达一次。

会话保持

MQTT 没有假设设备或 Broker 使用了 TCP 的保活机制^4,而是设计了协议层的保活机制:在 CONNECT 报文里可设置 Keepalive 字段,来设置保活心跳9 c :包 PINGREQ/PINGRES` K : r % S ! { gP 的发送时间间# d B隔。当长时间无法收到设备的 PINGRE~ i bQ 的时候,Broker 就会认为设备已经下线

总的来说,Keepalive 有I k 6 Y w s e 6两个作用:

  • 发现对` ] 0 ] k端死亡或者网络中断
  • u 4 ? _ 0 L i o长时Q 3 ] l }间无消息交互的情况下,保持连接不被网络设3 I j B k ( I z备断开

对于那些想要在重新上线后,重新收到离线期间错过的消息i Y .的设备,MQTT 设计了持( S Q久化连接:在 CONNECTe ` 4 } v 报文里可设置 CleanSession 字段为 False,则 Broker 会为终端存储:

  • 设备所有的订阅
  • 还未被设备确认的 QoS1 和 QoS 消息
  • 设备离线时o T ! w错过的消息

在线状态感知

MQTT 设计了遗愿(Last Will) 消息,让 Broker 在发现设n i / G K R a备异常下线的情况下,帮助设备发布一条遗愿消息到指定的主题。

实际上在某些 MQTT 服务器的实现里 (比如 EMQ X),设备上线或下线的时候 Broker 会通过某些系统主题发布设备状态更新,更符合实际应用场景。

开源 MQTT 服务器如何选择

到目前为止,比较流行的开源 MQX Y CTT 服务器有几个:

  • Eclipse Mosquitto

使用 C 语言实现的 MQTT 服务器。Eclipse 组织还还包含了大量的 MQTT 客户端项目:https://www.eclipse.org/paho/#

  • EMQ X

使用 Erlang 语言开发的 MQTT 服务器,内置强大的规则引擎,支持许多其他 IoT 协议比如 MQTT-SN、 C& 8 K Z `oAP、LwM2M 等。

  • Mosca

使用 Node.JS 开发的 MQTT 服务器,简单易用。

  • VerneMQ

同样使用 Erlang 开发的 MQTT 服务器.

从支持 MQTT 5.0、稳定性、扩展性、集群能力等方面考虑,EMQ X 的表现应该是最好的:

  • 使用 Erlang OTP 开发,容错能力好 (电信领域 , F ,久经考验的语言,曾经做出过 99.9999999% 可用性的交换机设备I 3 ( a y q B^5)
  • 官方有大量的扩展插件可供扩展。有很多认证插件,数据存储(bacj H F Bkep 4 ; v 7nd)插件可供选择。可支持各种关o V 3 J系型数据库,NoSQL 数据库,以及常- 见消息队列如 Kafka,RabbitMQ,Pulsar 等
  • N w m [持集群,支持节点水平扩展
  • 单节点支持 2000K 并发连接
  • 支持规则引9 A p n擎和编解码

【云栖号在线课H a O K堂】每天都有产品技术专家分享!
课程地址:https://yqh.alR B t m Niyun.com/live

立即加入社群,与专家面对面,及时w , : R D w q n了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK

原文发布时间:2020-07-08
本文作者:edwardx
本文来自:“dockone”,了解相关信息可以关注“dockone”


  1. 1 ↩
  2. 2 ↩