写点什么

MQTT 协议详解及 v5.0 实践

作者:阿里云AIoT
  • 2022 年 8 月 24 日
    浙江
  • 本文字数:4092 字

    阅读完需:约 13 分钟

简介: MQTT 是基于 TCP/IP 协议栈构建的异步通信消息协议,是一种轻量级的发布、订阅信息传输协议。可在不可靠的网络环境中进行扩展,适用于设备硬件存储空间或网络带宽有限的场景。 MQTT 已逐渐成为 IoT 领域最热门的协议,也是国内外各大物联网平台最主流的传输协议,阿里云 IoT 平台很多设备都是通过 MQTT 接入。 本文将详细介绍 MQTT 协议的历史演进,以及阿里云 IoT 平台在 MQTT 协议层实践中的一些关键设计及思考。


本文主要包含了以下内容:

1)MQTT 协议演进历史及协议特点,总结和分析 MQTT 协议族的优缺点,分析和总结了为什么相比于其他协议,MQTT 适合 IoT,业内支持现状等。

2)阿里云 IoT MQTT3 和 5 协议在实践中的一些关键设计及思考。 包括连接复用、设备状态一致性、扩展增值能力设计等。

1. MQTT 协议详解

1.1 MQTT 协议演进

MQTT 最初由 IBM 于 20 世纪 90 年代发明,最初是用于石油管道的传感器与卫星之间数据传输。MQTT v3.1.1 于 2014.10 月正式发布,与此同时 v3.1.1 已成为 OASIS 协议标准(就是 3.1.1 已升级为国际物联网标准)。正如 HTTP 为人们通过 web 分享信息铺平了道路一样,MQTT 标准化能将几十亿低成本、IoT 设备连接到网络。毫无疑问,MQTT 是当前最主流、增长最迅速的 IoT 应用层传输协议,目前,阿里云 IoT 平台许多在线设备都是通过 MQTT 接入的。


image


MQTT v5.0 于 2018.5 月正式发布,2019 年 3 月,v5.0 成为了新的 OASIS 标准。v5.0 在 v3.1.1 的基础上做了较大的改变且不做向下兼容,显然是有太多的新东西要被引入,所有现有的实现要重新实现。 此次通过的 v5.0 是自 2014 年的 v3.1.1 以来最重要的协议升级,新协议能适应近年来行业发展的新需求,同时也为未来物联网行业发展的做了协议上的准备。 阿里云 IoT 平台从 2020.1 月开始支持 MQTT5.0。

1.2 MQTT 协议族

每一种协议都是在特定上下文、约束下得出的折中设计,从来都没有完美的协议。 MQTT 经过几十年的发展,针对不同场景已经演进出相对成熟的多版本协议。

1.2.1 MQTTv3

MQTTv3 协议是为在低带宽、不可靠的网络上工作的传感器而设计的基于 TCP 的应用层协议,适用于 IoT 场景。 MQTT 报文设计紧凑,可在严重受限的硬件设备和低带宽/高延迟的网络上实现稳定传输。它具有以下几项重要特性:使用发布/订阅消息模式,支持一对多的消息分发,解除设备和业务之间的耦合; 报文格式设计精简, 适用于小规模数据传输以及资源受限的 IoT 设备。 固定头部是 2 字节,开销很小,支持 QoS0、QoS1、QoS2 三种消息 QoS。


MQTT3.1.1 在 MQTTv3 基础上引入了一些新特性, 主要包括:clientId 优化,支持 broker 给设备指定 clientId,增大了 clientId 最大长度。ack 响应优化,connect ack 中引入 session Present 标识,告诉设备当前 broker 有上次连接的会话信息,设备可以根据这个标记减少重复订阅等步骤。设备能够在等 broker 返回 connect ack 之前发布消息,这个特性有点类似 tls 的 false start, 适用于对于突发模式的设备端。


MQTTv3/v3.1.1 在实际应用中存在以下不足:1)错误码设计的不够完整,设备难以完整感知到 broker 的处理异常;2)不支持设备跟 broker 之间的能力发现/协商,broker 不能提供可选能力等。3)协议设计的过于精简,没有预留扩展空间,无法直接在协议层做扩展,协议能力相对简陋。4)对于一些高阶能力支持不够,例如协议层缺乏流控、优先级、报头压缩等功能。5)MQTT3 是基于 TCP 的应用层协议,TCP 固有的一些缺点也被 MQTT 继承了。

1.2.2 MQTT-SN

MQTT-SN(Sensor Networks) 是 MQTT 协议的传感器网络版本,最早用在 zigBee 无线网络中,主要面对电池供电,有限的处理器能力和存储能力的设备。只有很小的内存和 CPU,TCP 对于这些设备来说非常奢侈,甚至无法允许 TCP 协议栈。 还有一些网络,比如 zigBee,报文的长度在几百字节以下,无法承载太大的数据包。MQTT-SN 有主要特点:1) MQTT-SN 支持运行在链路层、IP、UDP 之上。2) QOS 增加了-1 级别,只用于传输,尽力而为,无保证。3)更丰富且开销更低的 Topic 类型。4)网络架构增加了 SN 网关。


1.2.3 MQTTv5

MQTT 5.0 在协议层提供了更大的自定义扩展空间,平台基于扩展点可支持更丰富的协议能力。v3.1 版本中,只能通过 overlay 方式,在业务层提供扩展能力。

MQTT5.0 主要特点如下:

1) 用户属性

设备上下行消息的时候支持携带用户自定义的属性,用户可以添加两端约定的属性数据,类似于 MQ 的标签,其中云端在转发应用消息时会保持所有用户属性的先后顺序。


2) 主题别名

设备上报消息的 topic 常常相对比较固定,数量不会特别多,那么只需首次发送消息的时候,通过携带 Topic 别名告知对端, 下次发送消息的时候,这个 topic 将会使用这个 Topic 别名的值来代替,即可减少上报 Publish 消息的报头。 通过将主题缩减为一个整型的数值可以达到减小 MQTT 报头大小的作用,从而减小传输流量开销,非常适用于带宽资源受限的设备。


3)请求/响应模式

MQTT3.1 版本中通信双方需要事先协商好请求主题和响应 topic。  MQTT5 新增了响应主题和相关数据,接收方只需关注怎么处理请求,而不用事先协商或考虑好怎么将响应正确返回给请求方。


4) 响应报文原因码和原因字符串

mqtt 3.1 协议中原因码的种类较少,这些原因码所能表示的含义很少,并且 mqtt3.1 不支持服务端通过 disconnect 报文断开连接,导致设备端仅根据响应难以定位问题。 mqtt5.0 有近 50 个原因码,绝大部分 ack 响应报文都包含了原因码,设备可以根据这些丰富的原因码定位请求是否成功以及问题。 MQTT5 议能反馈更多的错误信息到端上,并且支持云端通过 disconnect 报文主动断开连接, 设备端知道服务端发生了什么,因而能更灵活的应对。


5) 服务端能力协商

支持告知设备端 云端所支持的功能列表,避免设备端使用云端不支持的功能。

1.3 业内现状

1.3.1 开源社区 & 云产商


image


  • 目前主流 MQTT Broker 开源社区基本已经支持 v5.0,并且开源 SDK 也已经初步支持 v5.0,与此同时,国内 IoT 云厂商还没有支持 v5.0,但未来已来。

1.3.2 客户端 SDK 支持现状


image


2. MQTT 协议层实践

2.1 MQTT 应用架构

主要分为 6 大模块:

  • 基础接入模块:包括多版本协议编解码、多协议端口复用、会话管理、心跳检测、连接管理等。

  • 协议扩展模块:包括基于自定义协议扩展,实现的一系列扩展功能,包括通道解压缩、低功耗免 ping 等。

  • 增值消息服务:包括 Rrpc、广播、时钟同步、脚本前置解析等。

  • 业务埋点模块:设备行为统计、在线时长聚合、网络延时诊断等。

  • 安全防御模块:包括黑名单机制、入口流控等。

  • 高可用模块:包括流量分组调度、容灾降级等。

  • 运维管控模块:主要包括流量分组调度、限流管理、连接诊断


2.2 协议层设计挑战

  • 设备状态一致性策略设计,包括 session 管理机制、心跳检测机制、异地登陆问题、状态最终一致性策略。

  • 在 MQTT 发布/订阅异步分发模型上,如何满足多样的业务场景。例如同步调用、广播等。

  • 如何同时满足不同场景下设备对 MQTT 接入需求,单应用上如何同时支持两个版本 MQTT 协议

  • MQTTv3 协议过于精简,业务从 MQTT3 切换到 v5 的过渡时间,如何扩展协议层能力,提高客户接入体验。

2.3 MQTT 关键策略设计

2.3.1 设备在线状态

协议层本地有 session 管理器来对本地会话进行管理,通过心跳检测、会话自检来保证跟设备之间的连接状态一致性,当前平台单设备不支持同时同设备多端登陆,基于分布式会话,协议层通过分布式会话识别异地登陆,将异常连接踢下线。


设备状态一致性策略:设备到 MQTT 协议接入层之间是 tcp 长连接,通过心跳机制保证心跳周期内设备状态的最终一致性。同时通过分布式会话版本号,保证分布式会话并发更新安全,通过上行消息/心跳定时触发会话自检机制,解决异常情况下本地/分布式会话状态不一致的问题。


2.3.2 消息推送模式

MQTT 协议是基于 PUB/SUB 的异步通信模式,针对单设备纬度实现基础的发布/订阅推送外,还支持了复杂的消息推送方式:RRpc 和在线广播。


在传统的基于 PUB/SUB 通信模式的中间件中, 消息的 Producer/Consumer 只负责生产和消费,彼此之间不会直接通讯。 而在某些业务场景不仅仅是将消息投递至订阅方,订阅方收到消息后可能还会执行一些操作并返回结果,PUB/SUB 模式下实现这种请求/响应模式会非常繁琐,在 MQTT 中通信双方需要事先协商请求和响应 topic。


针对这一痛点,协议层在发布订阅模式之上构建了一套 Rpc 通讯模式,解决开发者痛点。Rrpc 模式允许 Producer 发出消息后,以同步形式等待 Consumer 消费这条消息并返回响应,达到类似 Rpc 的调用效果。Rrpc 模式使得 MQTT 应用具备了同步调用的能力,扩展了使用场景,使其具备更多的可能性。


image


  • 通过 topic 中包含的 messageId 匹配请求与响应,对业务数据零侵入

  • messageId 的生成与匹配、超时控制等逻辑,调用方无感知

  • 简化了业务方调用逻辑,扩展了 MQTT 使用场景。


2.3.3 多种类接入方式

MQTT 协议层针对不同场景支持多种 MQTT 接入方式,同时支持 tcp 直连、tls、ws、wss 等方式接入,用于满足不同场景接入需求。为了实现更好的网络穿透性,协议层实现了多协议端口复用,也就是一个端口同时支持多种协议。


image


  • 边解析边判断,处理效率高;

  • 节约常用端口,实现更好的网络穿透性

  • 内部能力扩展对设备侧无感知

  • 针对 MQTT 协议 5 和 3,通过协议解析也实现了同时兼容。


2.3.4 自定义协议扩展

MQTTv3 在实际应用中存在一些缺点,而 MQTTv5 生态的繁荣推广还需要很长时间的推进, 在 MQTT3 到 5 的过渡时间,我们在 v3.1.1 基础上通过 overlay 的方式,提供了扩展套件来解决客户痛点。

没有什么问题不是封一层解决不了的,如果有那就再封一层,思路:

  • 通过在建连 clientId 中扩展 ext 参数,实现端云之间能力协商

  • 通过扩展消息 topic 格式,实现支持自定义属性

  • 定义一套 ext 异常推送 topic 规范

  • 丰富接入增值能力,提高接入体验

  • 后端能力提前 ready 沉淀,5.0 升级可复用已有能力

2.4 未来展望

当前阿里云 IoT 平台协议层已支持了 MQTT 主流协议,并支持了多种协议接入方式,但还存在一些会进一步优化的地方:1)更丰富的消息质量模型,例如支持 QoS2,支持消息优先级等; 2)完善低功耗领域的网关侧支持,可以跟 SDK/边缘网关合作,支持 MQTT-SN 协议等

3. 参考资料

  1. https://developer.ibm.com/zh/technologies/messaging/articles/iot-mqtt-why-good-for-iot/

  2. http://docs.oasis-open.org/mqtt/mqtt/v5.0/cs02/mqtt-v5.0-cs02.html

  3. http://modelbasedtesting.co.uk/2018/04/09/a-story-of-mqtt-5-0/

  4. https://github.com/mqtt/mqtt.github.io/wiki/brokers

用户头像

阿里云AIoT

关注

还未添加个人签名 2022.04.22 加入

还未添加个人简介

评论

发布
暂无评论
MQTT协议详解及v5.0实践_物联网_阿里云AIoT_InfoQ写作社区