全面解析MQTT协议:从基础概念到核心组件
一、MQTT是什么
- 上篇其实已经介绍了MQTT,这里补充一下。
- MQTT(Message Queuing Telemetry Transport)是一种专为低带宽、不可靠网络环境或设备资源受限情况下设计的轻量级消息传输协议。它非常适合用于机器对机器(M2M)通信和物联网(IoT)应用中,因为它能够高效地在远程传感器和控制设备之间传递信息。
- MQTT基于发布/订阅模式工作,这使得它在构建灵活的消息传递系统时非常有用。通过这种模式,一个设备可以发布消息到特定的主题上,而其他设备则可以订阅这些主题以接收消息。这种方式允许消息生产者和消费者解耦,从而简化了应用程序的设计。
1、MQTT架构及角色
- **发布者(Publisher)**:发送数据的实体,可以向任意主题(topic)发布消息。
- **订阅者(Subscriber)**:接收数据的实体,它可以订阅一个或多个主题,并在相关主题上有新消息时收到通知。
- **代理服务器(MQTT Broker)**:作为消息中转站,接收来自发布者的消息并将它们分发给相应的订阅者。
2、MQTT通讯流程
- 连接:客户端通过TCP/IP连接到Broker,并使用CONNECT报文进行身份认证和会话参数协商。
- 订阅:客户端向服务器发送SUBSCRIBE报文用于创建一个或多个订阅。
- 发布消息:发布者将消息附带上指定的主题名发送给Broker,Broker接收到消息后,根据主题匹配规则将消息转发给所有已订阅该主题的订阅者。
- 取消订阅:客户端发送UNSUBSCRIBE报文给服务器,用于取消订阅主题。
- 断开连接:客户端发送DISCONNECT报文表示正常断开连接。
3、核心设计特点
- 轻量级:协议头最小仅2字节,二进制编码减少网络流量,适用于NB-IoT等窄带场景。
- 发布/订阅模式:通过Broker解耦发布者与订阅者,支持多对多通信和动态扩展。
- QoS分级保障:提供三种服务质量等级(QoS 0/1/2),从“最多一次”到“严格一次”递进满足不同场景需求。
- 会话持久化:支持断线重连恢复未接收消息,通过Clean Session标志控制离线消息存储策略
4、MQTT 控制报文格式
每个MQTT控制报文都由三部分组成:
- **固定报头(Fixed Header)**:所有控制报文都包含这个部分,它包含了报文类型和一些标志位。
- **可变报头(Variable Header)**:某些类型的控制报文包含这部分,具体内容取决于报文类型。
- **有效载荷(Payload)**:某些类型的控制报文包含这部分,例如PUBLISH报文的有效载荷就是消息内容。
5、MQTT 控制报文类型
MQTT定义了以下几种控制报文类型:
- CONNECT - 客户端到服务器的连接请求。
- CONNACK - 连接确认响应。
- PUBLISH - 发布消息。
- PUBACK - 发布确认(QoS 1消息)。
- PUBREC - 接收到发布(QoS 2消息的第一步)。
- PUBREL - 发布释放(QoS 2消息的第二步)。
- PUBCOMP - 发布完成(QoS 2消息的第三步)。
- SUBSCRIBE - 订阅请求。
- SUBACK - 订阅确认。
- UNSUBSCRIBE - 取消订阅请求。
- UNSUBACK - 取消订阅确认。
- PINGREQ - 心跳请求。
- PINGRESP - 心跳响应。
- DISCONNECT - 断开连接通知。
6、协议头
- CONNECT 报文的协议头包括协议名(如MQTT)、版本号、连接标志(Connect Flags)、保持连接时间(Keep Alive Timer)等信息。
- CONNACK 报文包含一个连接确认标志和返回码,表明连接尝试的结果。
7、心跳机制
- PINGREQ 和 PINGRESP 是用来检测客户端和服务端之间连接状态的心跳机制。客户端会定期发送PINGREQ报文给服务端,如果服务端正常工作,则会回复一个PINGRESP报文。这有助于确保双方的网络连接仍然活跃。
8、消息服务质量(QoS)
MQTT定义了三种服务质量等级,用来保证消息传递的可靠性:
- QoS 0:
- 工作原理:发布者发送消息给Broker后,不等待任何确认直接认为消息发送成功。
- QoS 1: 至少一次,确保消息至少被传递一次,但可能会重复。
- 工作原理
- 发布者向Broker发送带有PUBLISH报文的消息,并期待收到一个PUBACK响应作为确认。
- 如果在一定时间内没有收到PUBACK,发布者会重发消息,这可能导致消息重复。
- 工作原理
- QoS 2: 仅一次,确保消息只到达一次,是最可靠但也最耗资源的方式。
- 工作原理:这是最复杂也是最可靠的QoS级别,确保每条消息只被处理一次。它涉及四个步骤:
- 发布者向Broker发送带有唯一标识符(Packet Identifier)的PUBLISH报文。
- Broker接收到消息后,发送PUBREC响应给发布者。
- 发布者收到PUBREC后,发送PUBREL报文给Broker。
- Broker确认PUBREL报文后,发送PUBCOMP响应给发布者,完成整个过程。
- 详细解释:
- PUBLISH:客户端向Broker发送一条消息,并附带一个唯一的Packet Identifier(包标识符)。这条消息将尝试送达Broker。
- PUBREC:一旦Broker成功接收到该消息,它会回应一个PUBREC(发布收到)消息给客户端。这表示Broker已收到消息并记录下来,但还未完全确认处理完毕。
- PUBREL:客户端在收到PUBREC后,需要发送一个PUBREL(发布释放)消息作为回应。这一步告诉Broker,“我已经知道你收到了我的消息,现在你可以处理它了”。
- PUBCOMP:最后,Broker接收到PUBREL消息后,发送一个PUBCOMP(发布完成)消息给客户端。这标志着整个消息传递过程结束,消息已被成功处理且保证不会重复。
- 工作原理:这是最复杂也是最可靠的QoS级别,确保每条消息只被处理一次。它涉及四个步骤:
二、MQTT和TCP有什么区别?
MQTT(Message Queuing Telemetry Transport)和TCP(Transmission Control Protocol)是两种不同的协议,它们在计算机网络中扮演着不同的角色。
- 层级与作用:
- TCP 是传输层协议,负责提供可靠的、面向连接的通信服务。它确保数据能够准确无误地从一个端点传输到另一个端点,并处理诸如数据包重传、流量控制等问题。
- MQTT 是一种应用层协议,设计用于轻量级的消息发布/订阅模式通信。它构建于TCP之上(尽管也可以基于其他提供有序、无数据丢失、双向连接的网络协议),旨在为物联网设备提供高效的数据交换机制。
- 使用场景:
- TCP 广泛应用于需要可靠数据传输的各种网络通信中,如网页浏览(HTTP/HTTPS)、文件传输(FTP)、电子邮件(SMTP、IMAP、POP3)等。
- MQTT 主要用于资源受限的设备或低带宽、高延迟或不可靠的网络环境中的机器对机器(M2M)通信和物联网(IoT)应用。它特别适用于那些需要最小化网络带宽和设备资源消耗的应用场景,比如智能家居、工业自动化、车联网等。
- 功能特点:
- TCP 提供了错误检查、排序以及重传机制来保证数据的完整性。
- MQTT 则提供了发布/订阅模型,支持服务质量(QoS)等级、遗嘱消息等功能,使得它非常适合于实时消息传递系统。
总结来说,TCP是一个底层的传输协议,负责数据的可靠传输;而MQTT则是一个高层的应用协议,利用TCP提供的可靠性实现特定应用场景下的消息通信。MQTT依赖于TCP(或其他类似的传输层协议)来保证其消息传输的可靠性。
对比其他协议的优缺点
1、MQTT vs HTTP
- 优点:
- 带宽效率:MQTT使用发布/订阅模式,减少了不必要的数据传输,特别适合于低带宽环境。而HTTP通常为请求-响应模型,可能消耗更多的带宽。
- 实时性:MQTT设计之初就考虑了实时性,通过保持长连接可以实现快速的消息传递。相比之下,HTTP需要每次建立新的TCP连接,增加了延迟。
- 资源占用:MQTT在设备端占用较少的资源,对于资源受限的设备更加友好。
- 缺点:
- 通用性:HTTP作为一种广泛使用的Web协议,在大多数网络环境中都有很好的支持,而MQTT可能需要额外配置Broker服务器。
- 开发难度:对于熟悉Web开发的团队来说,HTTP可能更容易上手,而MQTT则需要一定的学习成本。
2、MQTT vs CoAP
- 优点:
- 可靠性:MQTT提供了服务质量(QoS)等级,确保消息的可靠传递,而CoAP默认是尽力而为(best-effort)的服务质量。
- 扩展性:MQTT支持大量的主题订阅者,适用于大规模部署;CoAP更适合点对点或小规模网络应用。
- 缺点:
- 复杂度:MQTT协议相对复杂,尤其是在处理QoS和会话管理方面。而CoAP基于RESTful架构,更简单直观。
- 能耗:由于MQTT需要维持长连接,可能会导致更高的能耗;CoAP采用UDP作为底层传输协议,能效更高。
3、MQTT vs AMQP
- 优点:
- 轻量级:MQTT的设计初衷是为了适应资源受限的设备,其报文格式简洁,易于解析。AMQP则更为重量级,适合企业级应用中复杂的队列管理和事务处理需求。
- 灵活性:MQTT的发布/订阅模型非常适合动态变化的网络拓扑结构,而AMQP虽然也支持发布/订阅,但更侧重于固定的消息路由规则。
- 缺点:
- 功能完整性:AMQP提供了丰富的消息路由机制、事务支持以及更强的安全特性,这些都是MQTT所不具备的。
- 社区支持:尽管MQTT拥有活跃的开源社区和广泛的行业支持,但在某些特定领域(如金融服务业),AMQP可能具有更深的专业积累和技术沉淀。
通过上述对比可以看出,每种协议都有其独特的优势和适用场景。选择合适的协议取决于具体的应用需求、网络条件以及系统约束等因素。MQTT以其高效、灵活的特点成为物联网应用中的首选之一,但在某些情况下,其他协议也可能提供更好的解决方案。
三、什么是MQTT Broker
- MQTT Broker,在MQTT协议架构中扮演着核心角色,可以被视为消息的中介或服务器。它的主要职责是接收来自发布者(Publishers)的消息,并根据订阅(Subscription)关系将这些消息转发给相应的订阅者(Subscribers)。换句话说,Broker就像是一个信息枢纽,它使得发布者和订阅者之间能够解耦,从而实现高效、灵活的消息传递机制。
1、MQTT Broker的主要功能包括:
- 消息传输:负责在发布者和订阅者之间可靠地传输消息。
- 主题管理:维护一个主题树(Topic Tree),用于组织和过滤消息。客户端可以通过特定的主题来发布或订阅消息。
- 连接管理:处理与客户端之间的连接,包括连接建立、保持和断开等操作。
- 安全性:提供认证和授权机制,确保只有经过验证的客户端才能进行通信,并限制它们只能访问被授权的主题。
- 持久化会话:支持持久化会话,允许客户端在重新连接时恢复之前的订阅状态,即使中间经历了网络中断等情况。
- 遗嘱消息:当客户端异常断开连接时,Broker可以根据该客户端预先设置的遗嘱消息通知其他客户端。
- 保留消息:存储最后一次发布的消息及其对应的主题,以便新订阅该主题的客户端能立即接收到最新的状态信息。
2、常见的MQTT Broker
- EMQX:
- EMQX 是一个高度可扩展的MQTT Broker,它支持MQTT 5.0和3.x版本,并且可以将保留消息持久化到磁盘上,以确保在Broker重启后仍然保持这些消息。
- Github地址:https://github.com/emqx/emqx
- Mosquitto:
- Eclipse Mosquitto也是一款流行的开源MQTT Broker,它支持保留消息的功能,并可以通过配置选项来启用或禁用保留消息的持久化。
- Github地址:https://github.com/eclipse-mosquitto/mosquitto
- VerneMQ:
- VerneMQ是另一个高性能、分布式的MQTT Broker,它基于Erlang/OTP构建,能够提供高可用性和容错能力。VerneMQ同样支持保留消息的持久化存储。
- Github地址:https://github.com/vernemq/vernemq
- HiveMQ:
- HiveMQ是一个企业级的MQTT Broker,它提供了强大的扩展性和灵活性,同时也支持保留消息的持久化功能。
- Github地址:社区版:https://github.com/hivemq/hivemq-community-edition
- NanoMQ:
- NanoMQ是一个轻量级的边缘计算MQTT Broker,适用于物联网边缘场景。虽然它主要针对资源受限的环境进行了优化,但它也支持保留消息,并可能根据具体部署情况进行持久化设置。
- Github地址:https://github.com/nanomq/nanomq
- ActiveMQ:
- ActiveMQ不仅支持AMQP等多种协议,也支持MQTT协议。它可以配置为持久化保留消息,以便在服务器重启后仍能保留这些消息。
- Github地址:https://github.com/apache/activemq
- RabbitMQ(通过插件):
- RabbitMQ本身不直接支持MQTT协议,但通过安装MQTT插件,它可以支持MQTT通信,并允许配置消息持久化策略,包括保留消息。
- Github地址:https://github.com/rabbitmq/rabbitmq-server
- 启用插件命令:
rabbitmq-plugins enable rabbitmq_mqtt
四、MQTT协议的技术演进与优化
1 MQTT 5.0核心增强
- 会话恢复:通过Session Expiry Interval参数支持会话状态保留最长两周,重连时间从8秒缩短至1.2秒。
- 原因码机制:提供53种标准错误码(如
0x85
表示QoS不支持),提升调试效率。 - 用户属性扩展:允许在报文中添加自定义键值对,支持业务元数据透传。
2 安全机制设计
- 传输层加密:强制使用TLS 1.3,支持PSK模式降低计算开销。
- 认证授权:基于OAuth 2.0的JWT令牌鉴权,结合ACL限制主题订阅权限。
- 设备指纹:提取MAC地址、固件版本生成唯一标识库,防止非法接入。
五、结论
MQTT协议作为一种轻量级的消息传输协议,专为资源受限的设备和低带宽、不可靠网络环境设计,已经成为物联网(IoT)应用中不可或缺的一部分。通过其高效的发布/订阅模式,MQTT不仅简化了应用程序的设计,还提高了系统的灵活性与可扩展性。在本篇文章中,我们详细探讨了MQTT的基础概念、核心组件、通讯流程及其与其他协议的对比,并介绍了几个流行的MQTT Broker实现。
随着物联网技术的不断发展,MQTT协议也在持续演进。例如,MQTT 5.0版本引入了更多的高级特性,如会话恢复机制、原因码机制及用户属性扩展等,进一步提升了协议的功能性和调试效率。同时,为了应对日益增长的安全需求,MQTT支持传输层加密、认证授权等安全措施,确保数据传输的安全可靠。
然而,选择适合自身应用场景的通信协议仍然至关重要。尽管MQTT在许多方面表现出色,但根据具体的应用需求、网络条件以及系统约束,其他协议如HTTP、CoAP或AMQP也可能提供更优的解决方案。因此,在实际项目开发过程中,开发者需要全面评估各种因素,以确定最适合的技术栈。
总之,MQTT凭借其高效、灵活的特点,在智能家居、工业自动化、车联网等多个领域得到了广泛应用。它不仅解决了传统通信方式中存在的问题,还为未来物联网的发展提供了坚实的基础。随着技术的进步,我们期待看到更多基于MQTT协议的创新应用出现,推动整个物联网生态系统向更加智能、互联的方向发展。