背景
在Linux中,执行ifconfig eth0的时候,能够看到以下信息,其中显示MTU为1500。
#ifconfig eth0
eth0: flags=5187<UP,BROADCAST,RUNNING,MASTER,MULTICAST> mtu 1500
怎么理解MTU
MTU(Maximum Transmission Unit,最大传输单元)是指在特定的网络层(如以太网、Wi-Fi等)上能够传输的最大帧的大小,该值是IP包的整个长度,即IP报文头部和负载的总和。
MTU = IP报文长度 = ip头长 + ip负载长度
标准的MTU大小是 1500 字节,这指的是IP报文的最大大小,也就是上面显示的1500值。不包括以太网头部(通常14字节)和尾部的帧检验序列(FCS,通常4字节)。
在实际的网络传输中,如果一个IP包的大小大于网络的MTU限制,那么在没有开启路径MTU发现机制(Path MTU Discovery)的情况下,这个数据包将会被IP分片传输,并在接收端进行分片重组。开启路径MTU发现可以帮助源主机发现沿途最小的MTU,从而避免分片,因为分片会增加额外的处理负担和潜在的传输问题。
什么情况下出现分片
ip报文的长度大于MTU就会出现,比如MTU 1500。
ping 1.1.1.1 -s 1472 -c 1 #没有分片 1472 + 28(ip协议头+icmp协议头) = 1500
ping 1.1.1.1 -s 1473 -c 1 #有分片 1473 + 28(ip协议头+icmp协议头) = 1501
当2台主机MTU不一致会出现什么情况?
在主机一上执行 ping server2 -s 1600,结果发现ping不通,为什么呢?遇到类似问题又该怎么排查?
可以通过ethtool -S来查询网卡的统计,会发现server2存在大量的rx_long_length_errors丢包,因为server2不支持接收超过1500的大包。
#ethtool -S eth0 | grep rx_long_length_errors
rx_long_length_errors: 17233438
总结
MTU是ip报文头长+负载的长度。ethtool -S 是一个很好排查网卡丢包的工具。一般可以通过以下命令观察,每秒的统计情况。
watch -d -n 1 'ethtool -S eth0 | grep -v ": 0"'