MTU 是什么
MTU(Maximum Transmission Unit)指某一层接口在不触发分片的前提下所能承载的最大 PDU 长度。对 IPv4 而言,常见以太网链路 MTU 为 1500 字节;蜂窝接口 MTU 可能由运营商或模组驱动给出不同默认值。物联网终端若在上层再封装 VPN、GRE、PPP、IPsec 等隧道,有效载荷空间会进一步缩小,形成“逻辑 MTU”远小于 1500 的情况,若应用仍按局域网习惯发送大包,就会在路径某处被分片或丢弃。
分片与重组的成本
IPv4 允许中间路由器分片,但现代网络更倾向于端到端 PMTUD(Path MTU Discovery)通过 ICMP“需要分片”报文动态发现路径 MTU。若蜂窝路径或企业防火墙屏蔽 ICMP,PMTUD 可能失败,导致 TCP 连接“能建立小数据、传大包即挂”。IPv6 则基本禁止中间分片,过大的包应由源端调整。物联网 MCU 协议栈若对分片重组支持不完整,也会出现偶发 UDP 丢包。
蜂窝场景的典型症状
用户常见现象包括:HTTPS 页面打开一半、MQTT 大消息失败、FTP 能登录不能传大文件。排查时可降低 TCP MSS、在 VPN 端设置更小的 tunnel MTU,或在应用层限制单帧大小。对于 NB-IoT 等窄带链路,运营商可能对包大小有更严格建议,需参考模组应用手册。调试工具可用 ping 不允许分片的方式探测路径最大可用尺寸。
工程建议
在架构设计阶段为“蜂窝 + 专网 + 云”链路预留 MTU 余量,例如在 VPN 集中器统一设置 TCP MSS clamp。固件中避免假设 MTU 恒为 1500;对 CoAP、LwM2M 等协议,优先采用块传输而非单次超大负载。记录现场运营商与卡批次,因不同 APN 出口设备 MTU 策略可能不同。
接口上限与隧道内层长度
某一跳的 MTU 是这一跳愿意一次性转发的最大分组长度。以太网常见的 1500 字节指的是 IP 包上限,不是应用可以随便填满的载荷。外面再套 PPP、GRE 或 IPsec 时,外层头部占用固定字节,内层可用长度变短;蜂窝接入网自己的 MTU 还可能低于 1500。发送端若仍按局域网习惯组包,分组会在某一跳被分片,或因不允许分片而被丢弃。IPv4 允许中间路由器分片,重组失败或只到达部分片时,整包作废。IPv6 要求源端自己控制长度,中间设备原则上不分片。
设计阶段就要为“蜂窝 + 隧道 + 云”留出余量:在隧道端或防火墙上做 TCP MSS 钳制,应用层对 UDP 和自有协议限制单次载荷。模组拨号成功后应读取网络给的 MTU,不要在固件里写成常数。NB-IoT 等窄带接入对包长更敏感,超长的证书链或未压缩的 JSON 会一次次触发重传。
禁止分片探测被中途丢掉
路径 MTU 发现依赖 ICMP 或 ICMPv6 的“包太大”反馈。企业防火墙或运营商把这些报文滤掉之后,TCP 三次握手仍能完成,因为握手包很小;一旦发送包含证书或图片的大段,连接就停住。症状像服务器故障,换一条不经隧道的路径又正常。应用把超时设得很短,分片重组还没完成就已经重传,空口上出现重复片。MCU 协议栈只实现了不分片的 UDP,偶发的大通知包丢失,小心跳一直正常,问题被归到业务服务器。不同 APN 的出口设备策略不同,实验室卡与量产卡表现不一致,固件却共用同一个载荷上限。
排查时用禁止分片的探测找出当前路径能通过的最大尺寸,再把应用载荷限到这个尺寸以下。双栈环境要分别看 IPv4 和 IPv6,详见蜂窝 IPv6。分组能出去不代表外网能按同一 MTU 主动连回来,入站方向还受NAT 与私网约束。记录卡批次和 APN,避免把某一出口的测量结果写成全部现网的常数。
给每一类报文规定上限:心跳、遥测、证书链和固件分片分开写,不要共用一个“尽量大”的缓冲。隧道打开后重新测量内层可用长度,并把该值写进配置而不是源码常数。TCP 由端点钳制最大段长度,UDP 和私有协议必须自己切片,协议栈不会替它们减小载荷。重组缓冲区在小内存模组上很有限,连续的分片风暴会把后面的正常包也丢掉。对比试验用同一张卡、同一个接入点,分别发送递增长度的探测包,记下第一包失败的长度,再留出余量作为应用上限。换运营商或换接入点名称后这项测量要重做。
探测时禁止中途分片,从短包加到失败为止,失败长度减去余量才是应用上限。隧道启用后这项测量重做。证书和固件包按该上限切片,不依赖中间路由器帮忙分片。不同接入点的结果分开保存,不把一张卡的测量写成所有批次的默认值。
小包正常、大包失败时先查路径长度,再查服务器。模组内存不足以重组时,表现为偶发丢通知而心跳仍在,这和服务器宕机不是同一类故障。