MQTT 3.1协议非严肃反思录
前言
MQTT 3.1协议在弱网络环境下(比如2G/3G等)表现不够好,因此才有了反思。
弱网环境下表现
手机等终端在弱网络环境下丢包情况会非常明显,连接MQTT Server成功率很低。相比单纯的请求-相应模型的HTTP,其成功率会比MQTT订阅成功高很多。
手 机终端在每次TCP断开或断网后,会即刻发起TCP重连,连接成功,会重复以前步骤依次发送连接命令(CONNECT),订阅命令 (SUBSCRIBLE),表明上看,这些过程没有任何问题,但问题就在于从终端成功建立到服务器的连接,到发送订阅命令,在弱网情况下,这个过程将会变 得很昂贵:
从TCP建立开始的三次握手到完整的订阅命令发送完毕,考虑到TCP堆栈的每次接收数据方响应ACK,这中间终端和服务器端至少产生了10次数据交互。
在网络变化频繁或者不太稳定的2G/3G网络环境下,这种过程显得有些冗长和不适应,同时会加重已经不堪的弱网络负载的负担。
弱网下,在任何一个阶段的执行过程中,都有可能产生突发性的网络中断的问题:
-
无法成功建立TCP链接,或死在三次握手期间,或数据包丢失在握手之后,或客户端连接超时过小
-
建立连接后,发送CONNECT命令后,或没接收到TCP ACK确认包,或客户端等待延时太小,导致订阅命令交互失败
-
发送SUBSCRIBLE命令后,但服务器端没收到,或因为丢包,或网络已断开,导致发送SUBSCRIBLE命令失败
-
成功发送SUBSCRIBLE命令后,或移动网络断开了(有些运营商针对认为HTTP的请求有超时判断),或等待超时,导致订阅失败
TCP是无感知的虚拟连接,中间断开两端不会立刻得到通知,否则就用不着心跳保活机制了。
举一个例子,线上的服务器根据日志分析,只接收到连接命令(CONNECT)但没有后续的订阅命令(SUBSCRIBLE)的情况,每天有上百万级别的数量。
总之,针对低速率弱网络环境,MQTT表现不怎么好。
改进点
业务改进点:
- 客户端的连接超时、等待超时设大一点,两秒太短,可设置长一些,比如10秒
- 服务器端支持在接收到用户发送CONNECT命令后,瞬间发送一些live data/hot data(早已缓存的数据),类似于HTTP请求-相应模型,目的嘛,一些热数据发送给终端要趁早,越快越好(所谓出名要趁早嘛);这个需要客户端、服务器端同时支持
协议改进点:
- CONNECT命令可变头部包含"MQisdp"太多余了,学院派风格嘛
- 允许在连接命令中负载(payload)中携带订阅Topic字符串
- 允许在连接命令中表示上次连接订阅的Topic发生变化否,携带订阅业务,虽冗余,但实用。 eg:订阅的Topic没有发生变化,TOPICCHANGE:0;退订,UNSUBSCRIBE:TOPICONE;SUBSCRIBE:TOPIC_TWO
- PUBLISH、PUBACK等支持的 Message Identifier 才16位,太短,实际业务无法做到全局唯一。引入mid和业务id的映射对应关系?那是状态,需要维护,代价还是蛮高的。业界流行看法,无状态化的架构才 是便于横向、竖向、纵向、四方向的扩展,呵呵。最好方式就是修改使之支持字符串形式,否则维护代价高!
- 心跳命令PINGREQ/PINGREQ可以做到一个字节传输,节省一个字节,有些强迫症的感觉嘛
- 低速率网络需要做一些兼容和调整
有些建议看似冗余,批量或打包处理总比单个处理更高效一些、更节省资源,弱网络环境要求交互要尽可能的少,数据嘛要的是瞬间抵达,越快越好。
严格的分层和业务解耦,会导致性能问题。好比当前Linux内核的TCP/IP网络堆栈分层很清晰,每一层都各司其职,但和直接略过内核态直接运行在用户态(User Space)的Packet I/O相比,处理性能不是在一个档次上,比如Netmap 、DPDK等。
MQTT-SN
针对没有TCP/IP等网络堆栈支持的终端环境,MQTT爱莫能助了。
在一些类似于传感器电子元件中,资源十分受限,计算能力不足,嵌入TCP/IP网络堆栈不现实,比较好的方式基于IEEE 802.15.4用于低速无线个人域网(LR-WPAN)的物理层和媒体接入控制层规范之上发送UDP数据包,每一个数据包最大128个字节。
MQTT-SN(MQTT For Sensor Networks)协议就是为了非常受限类似传感器而设的,协议流程架构比较有趣:
更多协议细节,有待进一步阅读。
TCP不是最适合的移动网络传输协议
先来算一下网络传输的字节数。
以太网帧头至少18个字节,IP头固定20个字节,TCP头20个字节(UDP头部8个字节),再加上电信宽带计费的PPPoE的8个字节:
- TCP数据包头部信息至少占有66个字节
- UDP数据报头部信息至少占有54个字节
UDP可以比TCP节省12个字节。
MQTT-SN协议选择使用UDP,可以看出其在节省资源方面的努力。
再看看弱网环境。
- 在网络可达情况下,UDP可以在TCP建立第一次握手期间就已经把数据送达目的地
- 完成三次握手期间,UDP客户端和UDP服务器在数据层面可以完成一次完整的交互(PING-PONG)
在网络不好的情况下,UDP的时效性会好于TCP,TCP长连接中间交换过多、使之建立完整交互的过程成功率就很低。此种情况UDP的低延迟和实时性呈现的结果会表现的很突出。
TCP或HTTP理论上是可靠连接,但是在网络不好的时候,也不是那么可靠。客户端一般提交HTTP请求之后,没有确认是否提交成功,在弱网环境下 会产生丢包,服务器端嘛收不到。另TCP网络堆栈会存在数据包重发机制 + 应用层重发请求,可能会导致内核处理多次数据包的重发(还有拥塞窗口会收缩,发包速度减慢),可能会加重弱网络的负载。
和TCP相比,UDP的无连接,代表了它快速,资源消耗小,突出表现就是延迟较小。至于数据包丢失没有重传,上层的业务层面应用协议/机制可以确保丢失的数据包重发或补发等,并且会更透明,安全的控性权。而TCP的包重发,上层应用没有控制权限。
连接协议方面:
- TCP面向连接会产生状态管理和维护,成本不小,比如经常看到的客户端reset异常等。一次完整的请求周期必须固定在一台服务器上
- UDP无连接的特性。每次请求的数据包可以随机分配到不同的机器上进行处理,可以做到完全无状态化横向扩展
总之,要实时性特诊,或者快速抵达终端的特性,不妨考虑一下UDP。不过呢,很多时候UDP和TCP大家会混合着使用,会互相弥补其不足。
小结
若MQTT协议不能够满足业务需求,或许可考虑选择定制,或简化流程,或使用UDP重新实现,或者使用TCP/HTTP作为补充等,不一而足。
转载自:
相关推荐
6. MQTT 3.1协议非严肃反思录 nieyong 2014-12-12 10:19 5. MQTT协议笔记之订阅 nieyong 2014-04-12 16:03 4. MQTT协议笔记之消息流 nieyong 2014-02-15 19:17 3. MQTT协议笔记之发布流程 nieyong 2014-02-10 23:...
### MQTT 3.1中文版协议详解 #### 概述 MQ遥测传输(MQ Telemetry Transport,简称MQTT)是一种高效、简单的消息传输协议,它最初由IBM和Eurotech共同开发并公开发布。该协议的设计初衷是为了解决受限环境下的数据...
netty-mqtt是一个基于Java开发的MQTT 3.1.1协议服务端与客户端,包含113个文件,其中包括87个Java源文件、8个XML文件、7个Iml文件、3个YAML文件、3个JKS文件、2个Factories文件、1个LICENSE文件和1个Markdown文件。...
MQTT(MQ遥测传输)是一种轻量级的、基于代理的发布/订阅消息传输协议。该协议的设计特点是开放、简单、轻量、易于实现,特别适用于受限环境,如带宽低、网络不可靠、处理器和内存资源有限的嵌入式设备。 MQTT协议...
MQTT协议是一种轻量级的消息传输协议,最早由IBM和Eurotech共同开发,目的是为了在资源受限的环境中提供一种开放、简单、轻量级且易于实现的通讯方式。这些环境包括但不限于网络成本高昂、带宽低下或者网络不稳定的...
### MQTT V3.1协议规范知识点详解 #### 协议简介 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是一种基于代理的轻量级发布/订阅消息传输协议,它由International Business Machines Corporation...
### MQTT 3.1 协议详解 #### 概览 MQTT (Message Queuing Telemetry Transport) 是一种轻量级、基于代理的发布/订阅消息传输协议,它旨在为低带宽、高延迟或不可靠的网络环境提供高效可靠的信息传输服务。MQTT ...
MQTT3.1及3.1.1是该协议的两个主要版本,主要在物联网(IoT)领域广泛应用。 在《MQTT3.1~3.1.1协议规范》中,主要包含了以下几个关键知识点: 1. **协议模型**:MQTT基于客户端-服务器架构,采用发布/订阅模式。...
MQTT3.1.1是MQTT协议的最新版本,对之前的3.1版本进行了优化和增强,旨在提供更高效、可靠和安全的数据交换。 **一、MQTT协议的核心概念** 1. **发布/订阅模型**:在MQTT中,消息发布者将数据发送到特定的主题...
MQTT协议,全称为消息队列遥测传输协议(Message Queuing Telemetry Transport),是一种轻量级的发布/订阅网络协议,它设计用于低带宽、不可靠网络和高延迟的网络环境。MQTT协议在物联网(IoT)、移动应用、传感器...
MQTT 协议 3.1.1 中文版 MQTT(Message Queuing Telemetry Transport)是一种轻量级的、基于发布/订阅模式的消息传输协议。它的设计思想是轻巧、开放、简单、规范,因此易于实现。这些特点使得它对很多场景来说都是...
### MQTT V3.1协议规范知识点详解 #### 一、MQTT协议简介 MQTT (Message Queuing Telemetry Transport) 协议是一种轻量级的发布/订阅模式的消息传输协议,由IBM和Eurotech共同开发并维护。此协议的设计初衷在于...
### MQTT-V3.1协议详解 #### 一、概述 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是由IBM开发的一种即时通讯协议。作为一种轻量级的基于代理的发布/订阅式消息传输协议,MQTT的设计目标是...
"MQTT 3.1" 和 "MQTT 5.0" 是两个重要的版本,它们各自包含了不同的特性和改进。MQTT 3.1.1是MQTT协议的早期稳定版本,而MQTT 5.0则是一个更新的版本,带来了更多的功能和优化。 **MQTT 3.1.1** 的主要特点: 1. **...
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级"通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。MQTT最大优点在于,可以以...
- **UTF-8字符集支持**:MQTT v3.1支持完整的UTF-8字符集,而非仅限于US-ASCII子集,提高了国际化能力。 #### 消息格式 MQTT协议中的每条消息由三部分组成:固定报头、可变报头(某些消息有)和消息体(payload)。...
**MQTT(Message Queuing Telemetry Transport)**是一种轻量级的发布/订阅式消息传输协议,主要用于设备间低带宽、高延迟或不稳定网络条件下的通信,特别适合物联网(IoT)和机器对机器(M2M)场景。MQTT 3.1.1 ...
MQTT(Message Queuing Telemetry Transport)是一种专为低带宽、高延迟或不可靠网络设计的轻量级发布/订阅消息协议。在物联网(IoT)领域,MQTT因其高效性和灵活性而广受欢迎,特别是在远程监控、智能家居、车联网...
### MQTT V3.1协议规范知识点详解 #### 一、MQTT协议简介 **MQTT**(Message Queuing Telemetry Transport)是一种轻量级的消息传输协议,由IBM与Eurotech共同开发,首次公开于1999年。此协议的设计目标在于提供一种...