基本概念
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议)由 Andy Stanford-Clark(IBM) 和 Arlen Nipper(Arcom, 现为 Cirrus Link) 于 1999 年发布,是一种基于发布/订阅模式的轻量级消息传输协议,专门针对低带宽和不稳定网络环境的物联网应用而设计,可以用极少的代码和有限的带宽,为联网设备提供实时可靠的消息服务。 MQTT 协议广泛应用于物联网、 移动互联网、 智能硬件、 车联网、 智慧城市、 远程医疗、 电力、 石油与能源等领域。
MQTT 协议提供一对多的消息发布,可以解除应用程序耦合,信息冗余小。该协议需要客户端和
服务端,而协议中主要有三种身份:发布者(Publisher)、代理(Broker,服务器)、订阅者(Subscriber)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,而消息发布者可以同时是订阅者。
发布订阅模式(Publish-Subscribe Pattern) 是一种消息传递模式, 它将发送消息的客户端(发布者) 与接收消息的客户端(订阅者) 解耦, 使得两者不需要建立直接的联系也不需要知道对方的存在。MQTT代理(Broker负责所有消息的路由和分发工作, 发布者将带有主题的消息发送给代理, 订阅者则向代理订阅主题来接收感兴趣的消息。MQTT中主题和订阅无法被提前注册或创建, 所以代理也无法预知某一个主题之后是否会有订阅者,以及会有多少订阅者, 所以只能将消息转发给当前的订阅者, 如果当前不存在任何订阅, 那么消息将被直接丢弃。
在 MQTT 发布/订阅模式中, 一个客户端既可以是发布者, 也可以是订阅者, 也可以同时具备这两个身份。当客户端发布一条消息时, 它会被发送到代理, 然后代理将消息路由到该主题的所有订阅者。 当客户端订阅一个主题时, 它会收到代理转发到该主题的所有消息。
一般来说, 大多数发布/订阅系统主要通过以下两种方式过滤并路由消息。
- 根据主题
订阅者向代理订阅自己感兴趣的主题, 发布者发布的所有消息中都会包含自己的主题, 代理根据消息的主题判断需要将消息转发给哪些订阅者。 - 根据消息内容
订阅者定义其感兴趣的消息的条件, 只有当消息的属性或内容满足订阅者定义的条件时, 消息才会被投递到该订阅者。
MQTT 典型特征
1.使用 TCP/IP 提供网络连接,提供有序、无损、双向连接;
2.具体有三种消息发布的服务质量(设备网络环境复杂);
3.小型传输,开销小,固定长度头部 2 字节,协议交换最小化,降低网络流量,轻量省带宽;
4.使用Last Will(遗言)通知有关各方客户端异常中断的机制(持续地会话感知能力);
5.数据无关(不关心 Payload 数据格式);
常见概念解释:
常见概念 | 解释 |
---|---|
MQTT客户端 | 一个使用MQTT协议的设备、应用程序 |
MQTT服务器 | MQTT服务器称为Broker(消息代理),其负责接收发布者的消息, 并将消息转发至符合条件的订阅者。 另外, 代理也需要负责处理客户端发起的连接、 断开连接、 订阅、 取消订阅等请求 |
主题(Topic) | 主题是 MQTT 进行消息路由的基础, 它类似 URL 路径, 使用斜杠 / 进行分层, 比如sensor/1/temperature。 一个主题可以有多个订阅者, 代理会将该主题下的消息转发给所有订阅者, 一个主题也可以有多个发布者, 代理将按照消息到达的顺序转发 |
服务质量(QoS) | 服务质量 ,表明此主题范围内传送到客户端所需的一致程度 |
会话(Session) | 每个客户端与服务器建立连接后就是一个会话,客户端和服务器之间有状态交互 |
订阅(Subscription) | 订阅包含主题筛选器(Topic Filter)和最大服务质量(QoS),一个会话可包含多个订阅,MQTT 还支持通过共享订阅的方式在多个订阅者之间实现订阅的负载均衡 |
发布 (Publish) | 负责将消息发布到主题上, 发布者一次只能向一个主题发送数据, 发布者发布消息时也无需关心订阅者是否在线 |
负载(Payload) | 消息订阅者具体接收的内容 |
遗言(Last Will) | 遗言机制,用来通知同一主题下其他设备发送遗言的设备已经断开了连接 |
主要优点介绍
轻量高效,节省带宽
MQTT 将协议本身占用的额外消耗最小化, 消息头部最小只需要占用 2 个字节, 可稳定运行在带宽受限的网络环境下且MQTT 客户端只需占用非常小的硬件资源, 能运行在各种资源受限的边缘端设备上。
可靠的消息传递
MQTT 协议提供了 3 种消息服务质量等级(Quality of Service),保证了在不同的网络环境下消息传递的可靠性。除QoS外,MQTT还提供了清除会话机制。
- QoS 0: 消息最多传递1次。如果当时客户端不可用, 则会丢失该消息。 发布者发送一条消息之后, 就不再关心它有没有发送到对方, 也不设置任何重发机制。
- QoS 1: 消息传递至少 1 次。包含了简单的重发机制, 发布者发送消息之后等待接收者的 ACK, 如果没收到 ACK 则重新发送消息。这种模式能保证消息至少能到达一次, 但无法保证消息重复。
- QoS 2: 消息只传送1次。设计了重发和重复消息发现机制, 保证消息到达对方并且严格只到达一次。
- 清除会话(Clean Session) 机制。 对于那些想要在重新连接后, 收到离线期间错过的消息的客户端, 可在连接时设置关闭清除会话, 此时服务端将会为客户端存储订阅关系及离线消息, 并在客户端再次上线后发送给客户端。
安全的双向通信
依赖于发布订阅模式, MQTT 允许在设备和云之间进行双向消息通信。 发布订阅模式的优点在于: 发布者与订阅者不需要建立直接连接, 也不需要同时在线, 而是由消息服务器负责所有消息的路由和分发工作。
MQTT 支持通过 TLS/SSL 确保安全的双向通信, 同时 MQTT 协议中提供的客户端 ID、 用户名和密码允许我们实现应用层的身份验证和授权。
在线状态感知
为了应对网络不稳定的情况, MQTT 提供了心跳保活(Keep Alive) 机制。 在客户端与服务端长时间无消息交互的情况下, Keep Alive 保持连接不被断开, 若一旦断开, 客户端可即时感知并立即重连。
同时, MQTT 设计了遗愿(Last Will) 消息, 让服务端在发现客户端异常下线的情况下, 帮助客户端发布一条遗愿消息到指定的 MQTT 主题。
MQTT 与其他协议对比
MQTT是应用层协议,和HTTP(S)/FTP/POP3/DNS/TELNET等处于同一级别,TCP/UDP是传输层协议。
MQTT vs HTTP
- MQTT 的最小报文仅为 2 个字节, 比 HTTP 占用更少的网络开销。
- MQTT 与 HTTP 都能使用 TCP 连接, 并实现稳定、 可靠的网络连接。
- MQTT 基于发布订阅模型, HTTP 基于请求响应, 因此 MQTT 支持双工通信。
- MQTT 可实时推送消息, 但 HTTP 需要通过轮询获取数据更新。
- MQTT 是有状态的, 但是 HTTP 是无状态的。
- MQTT 可从连接异常断开中恢复, HTTP 无法实现此目标。
- 针对松耦合下发布者对订阅者接收处理消息不清楚的情况,MQTT 5.0 增加了请求响应特性, 订阅者收到消息后向某个主题发送应答, 发布者收到应答后再进行后续操作
MQTT vs XMPP
- MQTT 报文体积小且编解码容易, XMPP 基于繁重的 XML, 报文体积大且交互繁琐。
- MQTT 基于发布订阅模式, 相比 XMPP 基于 JID 的点对点消息路由更为灵活。
- MQTT 支持 JSON、 二进制等不同类型报文。 XMPP 采用 XML 承载报文, 二进制必须 Base64 编码等处理。
- MQTT 通过 QoS 保证消息可靠传输, XMPP 主协议并未定义类似机制。
MQTT vs TCP
TCP协议诞生于1974年冷战期间。MQTT诞生于1999年互联网初期,TCP协议比MQTT协议诞生早了25年。TCP是OSI第四层的传输层协议。MQTT是第五层应用层协议。
-
协议定位
TCP设计考虑的是面向连接的、可靠的、基于字节流的传输层通信协议。
MQTT则是在低带宽高延迟不可靠的网络下进行数据相对可靠传输的应用层协议。 -
设计思想
TCP的核心思想是分组交换。
MQTT的核心思想是简单并适应物联网环境。 -
传输单位
TCP的传输单位是packet,当应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,TCP则把数据流分割成适当长度的报文段,最大传输段大小(MSS)通常受该计算机连接的网络的数据链路层的最大传送单元(MTU)限制。
MQTT的传输单位是消息,每条消息字节上限在MQTT Broker代理服务器上进行设置,可以设置超过1M大小的消息上限。这样,就可以用一条消息就发送上千条采集的数据,或者比较大的设备阴影文件。 -
技术挑战
TCP需要解决的问题是在IP包传输过程中,处理异构网络环境下的网络拥塞、丢包、乱序、重复包等多种问题。
MQTT解决的问题是,在低带宽高延迟不可靠的网络下和资源有限的硬件环境内,进行相对可靠的数据传输。 -
服务质量
TCP是一个可靠的流传输服务,通过ACK确认和重传机制,能够保证发送的所有字节在接收时是完全一样的,并且字节顺序也是正确的。
MQTT提供三种可选的消息发布的QoS服务等级。MQTT客户端和MQTT代理服务器通过session机制保证消息的传输可靠性。开发人员可以根据业务需要选择其中一种。 -
应用案例
TCP用于许多互联网应用程序,如WWW、email、FTP、SSH、P2P、流媒体。MQTT也是基于TCP的。
MQTT可以用于物联网数据传输、IM聊天软件等。
MQTT vs MQ(消息队列)
- 二者很多行为和特性非常接近, 比如都采用发布/订阅模式, 但是他们面向的场景却有着显著的不同。 消息队列主要用于服务端应用之间的消息存储与转发, 这类场景往往数据量大但客户端数量少。 MQTT 是一种消息传输协议, 主要用于物联网设备之间的消息传递, 这类场景的特点是海量的设备接入、 管理与消息传输。
- 在一些实际的应用场景中, MQTT 与消息队列往往会被结合起来使用, 以使 MQTT 服务器能专注于处理设备的连接与设备间的消息路由。 比如先由 MQTT 服务器接收物联网设备上报的数据, 然后再通过消息队列将这些数据转发到不同的业务系统进行处理。
- 不同于消息队列, MQTT 主题不需要提前创建。 MQTT 客户端在订阅或发布时即自动的创建了主题, 开发者无需再关心主题的创建, 并且也不需要手动删除主题。
快速开始教程:https://www.emqx.com/zh/blog/the-easiest-guide-to-getting-started-with-mqtt
ref:https://assets.emqx.com/resources/ebooks/beginners-guide-to-the-mqtt-protocol.pdf