MQTT比TCP协议好在哪儿?

希望详细点,不只是百度就能搜到的资料。
关注者
346
被浏览
95,443

14 个回答

MQTT 协议是建立在 TCP 协议之上的,

就好比汽车地盘上有四个轮胎就能跑了,但是想要大家开车更舒服,我们还是得给底盘加个壳。

为什么要在 TCP 协议之上再封装一层 MQTT 协议呢?

举个例子,如果你要用 TCP 协议做一个即时聊天室,那么你:

  1. 首先写一个服务器程序,监听某个端口,这样客户端就能连接上来了。然后大家就能向你的服务器发送数据了。
  2. 但是你不希望随便谁都能连接你的服务器并且往你的服务器里发东西,于是你写了一个注册页面,让别人先去注册账号,然后他们在客户端创建连接时发送的第一个TCP报文必须包含了账号密码。这样当你收到第一个报文之后,你就能判断这个连接是否合法了。
  3. 但是发过来的账号密码,具体摆在报文什么位置,也得 事先约定 好吧,不然怎么知道哪几位是账号哪几位是密码,于是你要求:第一个字节为1,用来告诉你这是一个请求连接的报文。然后第二个字节是报文剩下的长度(这个没啥异议,粘包处理必备),然后是“饼干熊最帅”这样一个固定的字符串(没啥意思,就是开心),后面紧跟着就是账号,然后是密码。但是账号有多长呢,所以账号第一个字节是账号的长度,剩下才是账号内容,这样就解决了“账号有多长”的问题了,密码同理。
  4. 如果账号密码不匹配就断开连接并且返回一句“xxxx off”,如果创建连接后半天不发送任何东西也断开连接。
  5. 现在大家的客户端都连接上来了,你在服务器保存了一个`账号:socket`的map,能通过任何一个账号找到这个人的socket并向他发送信息。接下来大家要开始聊天了。
  6. 在聊天室中,一个人发送的消息其他人都能收到,所以你添加了聊天室的概念,用户首先去你的web页面创建聊天室,然后会得到一个聊天室的ID。然后用户要加入聊天室,必须先发送一个加入聊天室的报文。然后你要求报文第一个字节为2代表加入聊天室的请求报文,然后是报文剩余长度,然后是聊天室ID,聊天室ID有多长?我们还是用第一个字节代表长度,剩下的内容为具体ID的形式来搞定。
  7. 现在有多个用户加入了聊天室,其中每个用户又都加入了多个聊天室。假设现在大家在聊天室A中开始聊天。用户甲向服务器发送消息,然后你发现你不知道这条消息是请求连接还是要加入聊天室还是干啥,所以发送消息也应该定义一种报文类型。于是你要求发送消息的报文的第一个字节为3,那么这个报文是发送到哪个聊天室的呢?于是你要求报文后面跟上聊天室ID,最后是具体的消息内容。
  8. 服务器收到第一个字节为3的消息,就知道这是一个聊天消息。然后根据上面带的聊天室ID以及你在服务器存储的用户和聊天室的关系,找到了这个聊天室里的所有人,然后你就把消息发给这里面的所有人了。


上面这个例子,在连接服务器(检查合法性、断开连接)、订阅主题(加入聊天室)、发布消息这些过程中,你约定的报文格式和设计的服务器处理逻辑就是 MQTT 协议的内容,当然我举的例子非常粗糙

真正的MQTT协议要求的处理逻辑和报文格式都完善很多,但是协议本身还是很简单的,具体内容去看 MQTT 的文档吧。

MQTT英文文档: MQTT Version 3.1.1

MQTT文档中文翻译: Introduction · MQTT协议中文版

一、MQTT与TCP的区别

诞生时间

TCP协议诞生于1974年冷战期间。

MQTT诞生于1999年互联网初期,TCP协议比MQTT协议诞生早了25年。

Ashton提出IoT概念也是在1999年,因此MQTT协议生逢其时。当时MIT Auto-ID Labs的Kevin Ashton为了把宝洁的供应链上的RFID标签和互联网连接起来,在1999年第一个提出了IoT这个概念。

发明人

TCP协议的发明人是Vinton Cerf(下图左,曾在IBM工作过两年)和Robert Elliot Kahn(下图右)。

MQTT的发明人是IBM的Andy Stanford-Clark(右)和Arcom的Arlen Nipper(现为Eurotech的CTO)。

2009年MQTT协议诞生10周年生日

发明起因

TCP协议和MQTT协议的设计都与卫星通信有着直接的联系。

1972年时,Kahn在IPTO公司参与了一个卫星通信网络项目,他就搞了个子项目来搭建卫星基站的无线电数据包通信网络。通过这个项目的经验,他发现有必要开发一个通用的开放架构的网络模型,从而让不同软硬件的网络都可以互相通信。在1973年Vinton Cerf也参与了这个项目,他们俩于同年实现了TCP的第一个版本。1974年的时候,TCP协议规范正式发布,编号为RFC 675。

在20世纪90年代中期IBM在帮助石油和天然气公司客户设计有效的数据传输协议时,就出现了对MQTT这种物联网环境下的数据传输协议的需求。

当时,为了实现数千英里长的石油和天然气管道的无人值守监控,采取的设计方案是将管道上的传感器数据通过卫星通信传输到监控中心。

这种应用场景有如下几个特点:

  • 石油天然气管道线路非常长,要接许多沿线的数据采集网关;服务器要能接成千上万个通信客户端;
  • 石油管道传感器的数据采集频率不高,不需要一下子传输大量数据;
  • 现场采集网关由于量大,考虑到采购成本,CPU和存储等计算资源都很有限;
  • 石油管道会穿越很多无人区,附近没有网络设施,因此使用卫星通讯最为经济;
  • 高轨道的GEO卫星站得高看得远,覆盖范围广,但轨道高延迟就大了。中低轨道的LEO/MEO卫星延迟小,但是覆盖区域有限,每天都会出现卫星切换时的网络中断。因此需要客户端和服务器端都能够保留消息收发状态,在网络恢复正常后继续发送;
  • 而且卫星链路带宽低(当然也有高带宽的),通信流量费用高昂;因此需要尽量节省传输的消息的流量开销;
  • 有些数据发送失败,不需要重发。但是有些消息比如阀门泄露告警或控制石油管道阀门的命令,就必须要在网络有问题的情况下也要能确保发送成功。

myriota这家提供物联网数据LEO卫星传输服务的公司,流量报价是1M字节的数据500美元/月。因此,每次传输节省几个字节也能省不少钱。

因此,针对石油管道传感器和控制装置数据采集和控制设计的传输协议需要满足如下要求:

  • 服务器要能接成千上万个客户端;
  • 每次消息传输的数据量不大;
  • 协议客户端软件要能在CPU和存储等计算资源都很有限的单片机、单板机、RTU等上运行;并能方便的实现移植到不同的硬件上;
  • 带宽低,通信流量费用高昂;需要最大限度地减少传输消息大小;
  • 卫星不会24小时都覆盖得到,会有段时间发生卫星通信中断;预期会遇到频繁的网络中断(低带宽,高延迟,不可靠,高成本运行的网络)。需要传输协议能够异步管理消息。在卫星通信中断时:MQTT网络中的服务器/代理可以保存和转发从客户端到客户端的消息,如果断开连接,它将能够在以后重新连接时获取消息。
  • 在环境允许的情况下提供传统的消息服务质量。提供不同等级的“服务质量”。

协议位置

TCP是OSI第四层的传输层协议。

MQTT是基于TCP的七层应用层协议。

协议定位

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协议的特点

  1. mqtt提供了qos0、qos1和qos2的不同的消息发送的服务质量,简化了消息发送不同服务质量的工作量。收发双方根据业务需要选择,可以选择所需的服务等级。MQTT客户端和broker端底层通过session来保障不同的qos等级。TCP协议需要自己实现类似机制,而MQTT自带这一功能,无需应用开发人员重复造轮子。

2. mqtt可以根据不同topic来实现应用消息的业务划分。另外还有灵活的topic订阅匹配的机制。

3. mqtt支持双向的通信,只需要将订阅者和发布者方向倒过来。这样就可以实现远程控制、远程下发、远程升级等功能。当然,tcp或者http也可以,只不过没这么直观方便。

4. mqtt与自定义的tcp的物联网协议相比,更为标准化,降低与第三方物联网服务集成的工作量。

5. mqtt针对物联网传输的2G/4G/5G流量费用,最大限度减少了传输流量,流量比http或者xmpp iot之类的要低。由于许多物联网应用需要24*7不间断发送数据,节约流量费用还是很重要的。当然payload用二进制协议,不用json或xml,可以更节约流量。

6. 异常情况下,有LWT遗嘱机制,通知相应topic的订阅者客户端已经离线了。

7. 正如https之于http,mqtts支持TLS安全,保证数据传输过程的安全性。

8. mqtt协议轻巧、简单,容易实现,mqtt客户端哪怕在单片机中也可以运行。这一点在物联网应用中挺重要的,因为很多物联网现场的采集硬件都是基于单片机开发的。

9. mqtt支持一对多的消息分发。根据Eclipse的MQTT客户端paho的wiki,paho是个新西兰毛利语的一个动词,指广播,读作爸(长音)ho。 maoridictionary.co.nz/s 。下面是paho的毛利语的意思: pāho (verb) to broadcast, make widely known, announce, disseminate, transmit (via the Maori dictionary)。

10. mqtt客户端connect时,可以带有用户名和密码,用于验证客户端。服务端可以根据clientid、IP地址、用户名等进行ACL访问控制。可以通过自定义应用消息实现客户端对服务端的身份验证。

11. 有商业和开源的mqtt broker供选择。支持ACL访问控制、集群、共享订阅、重要指标dashboard、sysadmin api、插件扩展、对topic或session或clientid的tracing调试等高级功能,大大简化服务器端的开发工作量。实际应用中,只需要写发布和订阅接口函数即可,中间过程对应用开发人员透明。

12. 可以通过MQTT over websocket来穿越防火墙,不需要开1883MQTT或8883MQTTS端口。


三、MQTT发明人介绍

Andrew Stanford-Clark拥有东英吉利大学计算机研究和数学学士学位,后来又获得了并行计算方向的博士学位。

他于1991年加入IBM的“通信软件”小组。斯坦福 - 克拉克在IBM内部担任过多个职位,主要负责并行处理和消息中间件。

1999年,他与Arlen Nipper合作编写了第一版MQ遥测传输(MQTT)协议。

2002年,他成为IBM Academy of Technology的成员,并成为IBM Master Inventor(要有40个以上的发明)。他于2007年成为IBM杰出工程师。

2010年,他成为Smart Energy Technologies的首席技术官,Smart Energy Technologies是IBM智慧地球战略的组成部分。

更多精彩文章,请关注我的专栏 物联网技术杂谈

我的专栏文章目录索引: 与子同袍:【物联网技术杂谈】专栏目录索引