MQTT3.1与UDP时效性分析

2023-05-16

前言

MQTT 3.1协议在弱网络环境下(比如2G/3G等)表现不够好,因此才有了反思。

弱网环境下表现

手机等终端在弱网络环境下丢包情况会非常明显,连接MQTT Server成功率很低。相比单纯的请求-相应模型的HTTP,其成功率会比MQTT订阅成功高很多。

手机终端在每次TCP断开或断网后,会即刻发起TCP重连,连接成功,会重复以前步骤依次发送连接命令(CONNECT),订阅命令(SUBSCRIBLE),表明上看,这些过程没有任何问题,但问题就在于从终端成功建立到服务器的连接,到发送订阅命令,在弱网情况下,这个过程将会变得很昂贵:

从TCP建立开始的三次握手到完整的订阅命令发送完毕,考虑到TCP堆栈的每次接收数据方响应ACK,这中间终端和服务器端至少产生了10次数据交互。

在网络变化频繁或者不太稳定的2G/3G网络环境下,这种过程显得有些冗长和不适应,同时会加重已经不堪的弱网络负载的负担。

弱网下,在任何一个阶段的执行过程中,都有可能产生突发性的网络中断的问题:

  1. 无法成功建立TCP链接,或死在三次握手期间,或数据包丢失在握手之后,或客户端连接超时过小

  2. 建立连接后,发送CONNECT命令后,或没接收到TCP ACK确认包,或客户端等待延时太小,导致订阅命令交互失败

  3. 发送SUBSCRIBLE命令后,但服务器端没收到,或因为丢包,或网络已断开,导致发送SUBSCRIBLE命令失败

  4. 成功发送SUBSCRIBLE命令后,或移动网络断开了(有些运营商针对认为HTTP的请求有超时判断),或等待超时,导致订阅失败

TCP是无感知的虚拟连接,中间断开两端不会立刻得到通知,否则就用不着心跳保活机制了。

举一个例子,线上的服务器根据日志分析,只接收到连接命令(CONNECT)但没有后续的订阅命令(SUBSCRIBLE)的情况,每天有上百万级别的数量。

总之,针对低速率弱网络环境,MQTT表现不怎么好。

改进点

业务改进点:

  1. 客户端的连接超时、等待超时设大一点,两秒太短,可设置长一些,比如10秒
  2. 服务器端支持在接收到用户发送CONNECT命令后,瞬间发送一些live data/hot data(早已缓存的数据),类似于HTTP请求-相应模型,目的嘛,一些热数据发送给终端要趁早,越快越好(所谓出名要趁早嘛);这个需要客户端、服务器端同时支持

协议改进点:

  1. CONNECT命令可变头部包含"MQisdp"太多余了,学院派风格嘛
  2. 允许在连接命令中负载(payload)中携带订阅Topic字符串
  3. 允许在连接命令中表示上次连接订阅的Topic发生变化否,携带订阅业务,虽冗余,但实用。 eg:订阅的Topic没有发生变化,TOPICCHANGE:0;退订,UNSUBSCRIBE:TOPICONE;SUBSCRIBE:TOPIC_TWO
  4. PUBLISH、PUBACK等支持的 Message Identifier 才16位,太短,实际业务无法做到全局唯一。引入mid和业务id的映射对应关系?那是状态,需要维护,代价还是蛮高的。业界流行看法,无状态化的架构才是便于横向、竖向、纵向、四方向的扩展,呵呵。最好方式就是修改使之支持字符串形式,否则维护代价高!
  5. 心跳命令PINGREQ/PINGREQ可以做到一个字节传输,节省一个字节,有些强迫症的感觉嘛
  6. 低速率网络需要做一些兼容和调整

有些建议看似冗余,批量或打包处理总比单个处理更高效一些、更节省资源,弱网络环境要求交互要尽可能的少,数据嘛要的是瞬间抵达,越快越好。

严格的分层和业务解耦,会导致性能问题。好比当前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)协议就是为了非常受限类似传感器而设的,协议流程架构比较有趣:

Image

更多协议细节,有待进一步阅读。

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作为补充等,不一而足。

http://www.blogjava.net/yongboy/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MQTT3.1与UDP时效性分析 的相关文章

  • 丢包纠错码 (UDP)

    我不知道要寻找什么 因为我从 纠错代码 中得到的只是与您不知道错误位置的情况相关的内容 因此 这些代码比我需要的要复杂得多 而且效率低下 在下文中 请注意位等于数据包 因为只有整个数据包可能会丢失 因此位类比非常适合 是否有 ECC 考虑到
  • Android udp 多播与以太网

    大家好 我正在开发一个使用 udp 多播的项目 我有一台服务器通过以太网电缆发送多播 udp 数据包 我花了几周的时间阅读有关 android 上多播的所有帖子 但我仍然无法在我的 Asus Transformer Tablet 4 1 上
  • 如何使用 ZeroMQ 处理原始 UDP?

    我有一个客户 我无法更改其代码 但我想使用 重新 编写ZeroMQ插座 客户使用原始TCP和原始的UDP插座 我知道我可以使用ZMQ ROUTER RAW对于生的TCP插座 但是原始的怎么样 UDP数据流 ZeroMQ 中对 UDP 的支持
  • Java UDP中如何获取实际数据包大小`byte[]`数组

    这是我上一个问题的后续问题 Java UDP发送 接收数据包一一接收 https stackoverflow com questions 21866382 java udp send receive packet one by one 正如
  • 从 ANDROID 2.2 发送 UDP 包(HTC 希望)

    我有一个局域网 我想从我的 android htcdesire 发送一条 udp 消息到我的电脑 它们之间有一个 WLAN 路由器 问题是 UPD 消息永远不会到达 PC Android上的代码 package org example an
  • 通过 Internet 发送 UDP 数据包

    我正在尝试了解 P2P 去中心化网络的一些细节 我的问题如下 假设我有两台名为 comp1 和 comp2 的机器 现在 comp1 设置在我的家庭网络中的路由器后面 comp2 位于我的办公室中 也位于路由器后面 我是否可以像这样在 In
  • HTTP 是否使用 UDP?

    这可能是一个愚蠢的问题 HTTP 是否使用过用户数据报协议 例如 如果使用 HTTP 传输 MP3 或视频 它内部是否使用 UDP 进行传输 From RFC 2616 http www ietf org rfc rfc2616 txt 通
  • 搜索所有网络上的设备

    我想实现一个代码 通过它我可以列出网络上连接的 upnp 兼容媒体渲染器设备 我用谷歌搜索了这个并找到了以下代码扭曲的网站 https twistedmatrix com documents current core howto udp h
  • VS2015:应用程序无法正确启动(0xc000007b)

    我在 Visual Studio 2015 上为 Windows 10 PC 编写了代码 该应用程序主要关注 UDP 通信 我使用 boost 库 它工作正常 但当我将代码文件夹移至 Windows 7 时 我收到错误 应用程序无法正确启动
  • 什么是消息边界?

    什么是 消息边界 在以下情况下 TCP 和 UDP 之间的区别之一是 UDP 保留消息 边界 我理解之间的区别TCP and UDP 但我不确定的定义 消息边界 由于 UDP 在每个单独的数据包中包含目的地和端口信息 因此是否可以为消息提供
  • netty 4.x.x 中的 UDP 广播

    我们需要使用 Netty 4 0 0 二进制文件通过 UDP 通道广播对象 Pojo 在 Netty 4 0 0 中 它允许我们仅使用 DatagramPacket 类来发送 UDP 数据包 此类仅接受 ByteBuf 作为参数 还有其他方
  • Windows 操作系统中无法访问的 IP 套接字关闭时间

    这些代码通过用户数据报协议提供发送数据 下面有两个代码 当我使用第一个代码来处理无法访问的 IP 地址时 我得到了三秒的延迟 请查看新结果标题 只需打开新的 C 控制台应用程序并将这些代码粘贴到其中 第一个代码 using System u
  • 为什么我们可以将 sockaddr 转换为 sockaddr_in

    我明白为什么强制转换很有用sockaddr to sockaddr in 但我不明白这怎么可能 据我所知 它们的大小相同sockaddr in添加了sin zero使其大小相同 我想知道编译器如何知道从哪里获取信息sockaddr in如果
  • 您可以bind()和connect() UDP连接的两端吗

    我正在编写一个点对点消息队列系统 它必须能够通过 UDP 运行 我可以任意选择一侧或另一侧作为 服务器 但这似乎不太正确 因为两端都从另一端发送和接收相同类型的数据 是否可以绑定 和连接 两端 以便它们只能彼此发送 接收 这似乎是一种非常对
  • 使用 Boost.Asio 进行广播的问题

    如果问题之前已得到解答 我提前表示歉意 但我已经搜索并没有找到任何对我有帮助的东西 正如问题标题所示 我正在尝试将包从服务器广播到一组侦听任何消息的客户端 客户端将计算一秒钟内收到的消息数 服务器端的事情是这样的 class Server
  • 为什么 SNMP 通常在 UDP 上运行而不是 TCP/IP 上?

    今天早上 工作中出现了大问题 因为 SNMP 陷阱没有 通过 因为 SNMP 是通过 UDP 运行的 我记得在大学网络课上 UDP 不能像 TCP IP 那样保证传输 维基百科说 SNMP 可以在 TCP IP 上运行 但 UDP 更常见
  • 我应该害怕使用 UDP 进行客户端/服务器广播通话吗?

    我在过去的两天里阅读了每一篇StackOverflow问题和答案 以及googling当然 关于印地TCP and UDP协议 以便决定在我的用户应用程序和 Windows 服务之间的通信方法中应该使用哪一种 从我目前所看到的来看 UDP是
  • 尝试接收 UDP 多播时出现空指针异常

    在尝试了几次让简单的 UDP 多播接收器工作后 我感到很困惑 在我自己的代码无法按预期工作后 我尝试了 vertx 文档中发布的确切示例 DatagramSocket socket vertx createDatagramSocket ne
  • 为什么 Kademlia 使用 UDP?

    为什么Kademlia 分布式哈希表 http en wikipedia org wiki Kademlia使用 UDP 作为其网络传输协议 即使它不可靠 主要原因是您快速查询了许多以前从未建立过联系并且可能在查找过程中永远不会再看到的节点
  • 用于实时传输协议的开源 .net C# 库

    net中有好的RTP开源库吗 我的目的是用于音频和视频同步问题并提高每秒帧数速率 我对 RTP 不太了解 但你可能想看看本文 http www codeproject com KB IP Using RTP in Multicasting

随机推荐

  • linux离线搭建SVN服务器系列<二 >

    在linux离线搭建SVN服务器系列 lt 一 gt 里安装svn服务器后 xff0c 接下来就是安装svn客户端了 这里打算以windows客户端和linux为例进行说明 一 linux svn客户端 一 先安装linux svn客户端
  • NDK配置debug环境时:Error:FAILURE: Build failed with an exception

    Error FAILURE Build failed with an exception What went wrong Execution failed for task 39 app externalNativeBuildDebug 3
  • Android 集成OpenCV

    OpenCV下载 一 集成SDK 1 从官网下载最新的android sdk xff0c 这里下载的是4 5 4 2 创建Android项目 xff0c 将sdk以library方式引入项目中 sdk使用了kotlin xff0c 需要配置
  • MyEclipse 控制台等显示在底部

    虽然接触MyEclipse已经有了几年了 xff0c 但是底部的控制台 xff0c 服务 xff0c svn等等显示不清楚 今天百度了 xff0c 发现只要按 Window gt show view gt 选择你要固定在底部的选项 还真方便
  • 协方差与自相关

    协方差矩阵是一个矩阵 xff0c 其每个元素是各个向量元素之间的协方差 这是从标量随机变量 到高维度随机向量 的自然推广 假设是以个标量随机变量组成的列向量 xff0c 并且是其第i个元素的期望值 xff0c 即 协方差矩阵被定义的第i x
  • 基础解系

    基础解系首先是线性无关的 xff0c 简单的理解就是能够用它的线性组合表示出该 方程组的任意一组解 xff0c 基础解系是针对有无数多组解的方程而言 xff0c 若是齐次线性方程组则应是有效方程组的个数少于未知数的个数 xff0c 若非齐次
  • 机器学习实践指南:案例应用解析(第二版)

    试读及购买链接 机器学习实践指南2版代码及资源 原书中的360网盘链接因为360关闭网盘的原因已经失效 1 https pan baidu com s 1nw37A5N 2 http www hzbook com Books 9324 ht
  • 数学之路-python计算实战(7)-机器视觉-图像产生加性零均值高斯噪声

    图像产生加性零均值高斯噪声 xff0c 在灰度图上加上噪声 xff0c 加上噪声的方式是每个点的灰度值加上一个噪声值 xff0c 噪声值的产生方式为Box Muller算法 生成高斯噪声 在计算机模拟中 xff0c 经常需要生成正态分布的数
  • 数学之路-python计算实战(16)-机器视觉-滤波去噪(邻域平均法滤波)

    coding utf 8 code myhaspl 64 myhaspl com 邻域平均法滤波 半径为2 import cv2 import numpy as np fn 61 34 test3 jpg 34 myimg 61 cv2 i
  • Serializable和Parcelable序列化

    前言 Android中常用的序列化方式包含有两种 xff1a Serializable和Parcelable 其中Serializable是java中通用的对象序列化方法 xff0c 在Android实际内存操作时会更加偏向于实现Parce
  • R语言与数据模型(1)-平均,方差,中位数,分位数,极差

    1 求平均数 gt x lt c 1 10 20 30 40 50 NA 60 gt xm lt mean x gt xm 1 NA na rm表示允许缺失数据NA gt xm lt mean x na rm 61 TRUE gt xm 1
  • AI理论随笔-对称矩阵、正交矩阵与特征向量,特征值(2)

    一 如果 xff1a A A T 61 E AA T 61 E A A T 61 E
  • 英文过滤停用词

    span class token triple quoted string string 34 34 34 Created on Sun Nov 13 09 14 13 2016 64 author daxiong 34 34 34 spa
  • C语言随笔-去掉仅有\n的行

    include lt stdio h gt int main int argc const char argv char str 128 char linep strcpy str 34 12 35 56 n12 33 87 n n n n
  • python3.6-深入浅出视频

    课程收益 适合人群 python小白 xff0c 大数据和机器学习编程程序员 上机实践为主线 以最快的速度上手 快速入门 xff0c 还学到了python3的核心知识 https edu csdn net course detail 989
  • 数学之路(3)-机器学习(3)-机器学习算法-神经网络[11]

    多层感知器的代码 xff0c 需要一个比较复杂的调试过程 xff0c 不过也有一些方法来加快这一速度 xff0c 其中有几个地方要注意 xff1a 1 输入层 输出层 中间层的学习率和动量参数不能一样 xff0c 2 3个层的权值策略不能一
  • 14、iOS里面的富文本

    iOS里面的富文本 1 NSAttributedString属性概览表2 属性详解及应用2 1 NSAttributedString Key font 字体大小2 2 NSAttributedString Key paragraphStyl
  • 马化腾五兄弟:难得的创业团队

    http www donews com people 201105 455471 shtm 腾讯的马化腾创业5兄弟 xff0c 堪称难得 xff0c 其理性堪称标本 12年前的那个秋天 xff0c 马化腾与他的同学张志东 合资 注册了深圳腾
  • 选择创业团队的类型

    从不同的角度 层次和结构 xff0c 可以划分为不同类型的创业团队 xff0c 而依据创业团队的组成者来划分 xff0c 创业团队有星状创业团队 xff08 Star Team xff09 网状创业团队 xff08 Net Team xff
  • MQTT3.1与UDP时效性分析

    前言 MQTT 3 1协议在弱网络环境下 xff08 比如2G 3G等 xff09 表现不够好 xff0c 因此才有了反思 弱网环境下表现 手机等终端在弱网络环境下丢包情况会非常明显 xff0c 连接MQTT Server成功率很低 相比单