本文为看雪论坛优秀文章

看雪论坛作者ID:emqttx

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

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

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

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

MQTT 协议的诞生

MQTT was created by Andy Stanford-Clark of IBM, and Arlen Nipper (then of Arcom Systems, later CTO of Eurotech).^3

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

MQTT 协议设计原则

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

灵活的发布订阅和主题设计

发布订阅模式是传统 Client/Server 模式的一种解耦方案。发布者通过 Broker 与消费者之间通信,Broker 的作用是将收到的消息通过某种过滤规则,正确地发送给消费者。发布/订阅模式 相对于 客户端/服务器模式 的好处在于:

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

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

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

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

  • + 是匹配单层的通配符。比如 news/+ 可以匹配 news/sportsnews/+/basketball 可匹配到 news/sports/basketball
  • # 是一到多层的通配符。比如 news/# 可以匹配 newsnews/sportsnews/sports/basketball 以及 news/sports/basketball/x 等等。

MQTT 的主题是不要预先创建的,发布者发送消息到某个主题、或者订阅者订阅某个主题的时候,Broker 就会自动创建这个主题。

带宽消耗最小化

MQTT 协议将协议本身占用的额外消耗最小化,消息头部最小只需要占用 2 个字节。

MQTT 的消息格式分三部分:

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

MQTT 的主要消息类型有:

  • CONNECT / CONNACK
  • PUBLISH / PUBACK
  • SUBSCRIBE / SUBACK
  • UNSUBSCRIBE / UNSUBACK
  • PINGREQ / PINGRESP
  • DISCONNECT

其中 PINGREQ / PINGRESP 和 DISCONNECT 报文是不需要可变头部的,也没有 Payload,也就是说它们的报文大小仅仅消耗 2 个字节。

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

三个可选的 QoS 等级

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

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

QoS 0 是一种 "fire and forget" 的消息发送模式:Sender (可能是 Publisher 或者 Broker) 发送一条消息之后,就不再关心它有没有发送到对方,也不设置任何重发机制。

QoS 1 包含了简单的重发机制,Sender 发送消息之后等待接收者的 ACK,如果没收到 ACK 则重新发送消息。这种模式能保证消息至少能到达一次,但无法保证消息重复。

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

会话保持

MQTT 没有假设设备或 Broker 使用了 TCP 的保活机制^4,而是设计了协议层的保活机制:在 CONNECT 报文里可设置 Keepalive 字段,来设置保活心跳包 PINGREQ/PINGRESP 的发送时间间隔。当长时间无法收到设备的 PINGREQ 的时候,Broker 就会认为设备已经下线。

总的来说,Keepalive 有两个作用:

  • 发现对端死亡或者网络中断
  • 在长时间无消息交互的情况下,保持连接不被网络设备断开

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

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

在线状态感知

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

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

开源 MQTT 服务器如何选择

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

  1. Eclipse Mosquitto
    使用 C 语言实现的 MQTT 服务器。Eclipse 组织还还包含了大量的 MQTT 客户端项目:https://www.eclipse.org/paho/#
  2. EMQ X
    使用 Erlang 语言开发的 MQTT 服务器,内置强大的规则引擎,支持许多其他 IoT 协议比如 MQTT-SN、 CoAP、LwM2M 等。
  3. Mosca
    使用 Node.JS 开发的 MQTT 服务器,简单易用。
  4. VerneMQ
    同样使用 Erlang 开发的 MQTT 服务器.

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

  • 使用 Erlang OTP 开发,容错能力好 (电信领域久经考验的语言,曾经做出过 99.9999999% 可用性的交换机设备^5)
  • 官方有大量的扩展插件可供扩展。有很多认证插件,数据存储(backend)插件可供选择。可支持各种关系型数据库,NoSQL 数据库,以及常见消息队列如 Kafka,RabbitMQ,Pulsar 等
  • 支持集群,支持节点水平扩展
  • 单节点支持 2000K 并发连接
  • 支持规则引擎和编解码

MQTT 协议快速体验

MQTT 在线服务器

EMQ X MQTT 物联网云服务 提供了一个在线的公共 MQTT 5.0 服务器,不需要任何安装您就可以快速开始 MQTT 协议的学习、测试或原型制作。

该 MQTT 服务器的详细接入信息请见 EMQ 官网页面:免费的在线 MQTT 服务器。

MQTT 在线客户端

EMQ 也提供了支持浏览器访问的 MQTT 在线客户端工具,该工具支持通过普通或者加密的 WebSocket 端口连接至 MQTT 服务器,同时也支持缓存连接方便下次访问使用。

[^1]: The number of connected devices that are in use worldwide now exceeds 17 billion, with the number of IoT devices at 7 billion... https://iot-analytics.com/state-of-the-iot-update-q1-q2-2018-number-of-iot-devices-now-7b/
[^2]: The estimated installed base of smart meters (electricity, gas and water) is expected to surpass the 1 billion mark within the next 2 years. https://iot-analytics.com/smart-meter-market-2019-global-penetration-reached-14-percent/

mqtt判断设备是否在线_物联网的基石-mqtt 协议初识相关推荐

  1. mqtt判断设备是否在线_如何在 Python 中使用 MQTT

    Python 是一种广泛使用的解释型.高级编程.通用型编程语言.Python 的设计哲学强调代码的可读性和简洁的语法(尤其是使用空格缩进划分代码块,而非使用大括号或者关键词).Python 让开发者能 ...

  2. 判断设备网络状态_生成树RSTP,快速生成树协议,交换网络必用的破环协议,面试必备...

    一.RSTP 802.1w 标准定义了快速生成树协议 RSTP(Rapid Spanning Tree Protocol),该协议基于 STP 协议,对原有的 STP 协议进行了改进并实现了快速收敛. ...

  3. java判断用户是否在线_用JSP实现显示用户是否在线

    在一些博客网站和论坛里,我们能看到某个用户是否在线,或者显示有在线用户,而这个功能是怎么实现的呢? 大多数情况下,我们都是使用HttpSession来保存登录用户的信息,如果用户手动点击了[注销],我 ...

  4. MQTT客户端远程控制WIFI设备(阿里云物联网平台)

    MQTT客户端远程控制WIFI设备(阿里云物联网平台) MQTT客户端远程控制WIFI设备(阿里云物联网平台) 准备工作 配置Topic 调试 MQTT客户端远程控制WIFI设备(阿里云物联网平台) ...

  5. java实现mqtt服务端_基于Swoole使用MQTT协议连接阿里云物联网平台设备实现消息订阅

    阿里云物联网平台为设备提供安全可靠的连接通信能力,支撑设备数据采集上云,我们这里认为阿里云物联网平台是 MQTT 服务端,那么我们自己的设备作为客户端,应该如何实现消息订阅? 阿里云没有提供 PHP ...

  6. java 读取硬件设备发送数据_基于java的物联网设备控制系统源码分享,loT硬件智能化...

    基于Paas服务的物联网平台,用于快速开发.部署物联设备接入. 降低物联网企业研发.运维和运营成本,帮助企业将物联设备快速互联网化,提高物联网项目的落地能力. 系统截图 系统核心特性 1.可扩展性强 ...

  7. 阿里云物联网批量获取设备的在线离线状态

    一.背景 我们在做物联网的时候,除了控制设备进行一些操作之外.设备的在线离线显示也是很重要的.如果设备离线的话,此时用户操作设备,设备并不会做出反应.对用户而言,操作体验当然是非常不好的. 这边我们可 ...

  8. 笔记本电脑网络连接显示红叉_物联网设备的网络连接---上篇

    在一个物联网场景中,设备连接是底层基础.由于物联网设备的多样性,涉及到各个工业领域中的标准或规范,这就需要综合的软硬件技术将它们连接起来. 本文分别从物联网组网技术和传输协议的角度来介绍物联网系统所面 ...

  9. tcp实时传输kafka数据_将物联网数据和MQTT消息流式传输到Apache Kafka

    Apache Kafka是一个实时流媒体平台,在大型和小型组织中得到广泛采用.Kafka的分布式微服务架构和发布/订阅协议使其成为在企业系统和应用程序之间移动实时数据的理想选择.据一些人称,超过三分之 ...

  10. 物联网:SpringBoot 集成Websocket 前后端客户端 及 mqtt 实现设备联动

    项目背景: 实现人离开房间超过一定时间,自动关闭空调联动控制功能. 实现原理: 通过客流密度摄像机监测客流人数变化,发送订阅消息到mqtt 消息服务器,WEB后台服务器订阅mqtt主题,接收客流密度摄 ...

最新文章

  1. Linux drm显示系统的两种方案
  2. java.lang.NoSuchMethodError: org.springframework.beans.factory.annotation.InjectionMetadata.init(L
  3. spark之13:提交应用的方法(spark-submit)
  4. ABAP后台作业(background job)的几种状态
  5. 第十四期:5 个 JS 不良编码习惯,你占几个呢?
  6. IOS图标 HTML规范,IOS用户界面(UI)设计规范图表——APP设计师必看!
  7. @autowired注解注入为null_Spring @Autowired 注解自动注入流程是怎么样?
  8. SQL 错误: ORA-12910
  9. opencv-python学习一--人脸检测
  10. 2019美团技术沙龙合辑PPT下载
  11. chm sharp安卓版_CHM 阅读器
  12. 外星人笔记本计算机在哪里,笔记本电脑没声音,教您外星人笔记本没声音如何解决...
  13. c语言计算输入20个有符号整数,统计正整数,零,负整数的个数.操作,输入20个有符号整数,统计正整数.零.负整数的个数.并分别计算之和...
  14. 如何无痛写文章 - 《麦肯锡教我的写作武器》
  15. 2022国赛数学建模思路 - 复盘:生成规划模型
  16. JS 的 _.isEmpty()函数使用
  17. uva 1362 区间DP
  18. sql server 自定义列的自增规则
  19. 镜像与复制有什么区别_开发者如何快速精简容器云镜像?| 技术头条
  20. CSS重复线性渐变之画格子

热门文章

  1. 七类***各有“黑招”
  2. ES6 关于Set对象
  3. Linux下安装whl文件
  4. 服务器宕机可能的原因以及服务器宕机解决办法
  5. DOMContentLoaded、readystatechange、load、ready详谈
  6. 【BZOJ】3495: PA2010 Riddle
  7. JS正则表达式 替换首尾和中间的空格
  8. android 正五边形图表,Android自定义View-蜘蛛网属性图(五边形图)
  9. 服务器文件夹只读属性,修改云服务器上文件夹只读属性
  10. mysql外键约束_mysql 外键约束