MTU , Maximum Transmission Unit,最大传输单元。
一、基本概念
指通信协议某一层上面能传输的最大字节数。这个参数通常和网络接口有关。以太网MTU都是1500bytes。
一个英文字母占一个一节,假如要模拟发送最大的字节数,比如1500,就写1500个a。
每种协议头部和尾部字段都是规定好的,所以每种协议MTU减去头部尾部的长度剩下就是有效数据的长度。
分片,因为链路都会传输大数据的情况,假如这台机器正好不能把这个大包传输,这个时候分片的概念就出现了,在一端分片以后,另一端还需要进行重组,分片和重组对性能的损耗比较大,所以尽量减少分片情况出现,于是就有了链路MTU的概念。
链路MTU,整条链路,单次传输能传输的最大字节数。一般是由链路中最小的点决定的。这一点很好理解,就像不同大小水管拼接起来,是由最窄水管决定能传多少水。
在进行端到端的传输时,传输之前先定位出来这条路上最窄的水管能装多少水,之后就按照那个大小来发送。如何定位呢?
定位工具是常用的traceroute命令
traceroute主要是利用icmp错误包来判断端到端路径中的每一跳的延时,第一次先发ttl为1的包udp包,这时会收到第一跳路由器ttl为0,产生的icmp错误包,目的地不可达,依次增大ttl为 2,3,4…直到收到的错误包不是ttl超时而是udp端口不可达,这样就证明了确实到了对端。
二、定位手段
1.现象
最典型的现象,小包传输正常,大包传输失败,一般这种问题只能用抓包来看。
case 1:
场景抓包截图如下:
看第一副图,这个很明显client一直在努力的发 长度为 1460的包,直到对方发回来reset。这种小包正常,大包重传基本可以认定是mtu问题
server端,中间丢了包,所以一直发ack,告诉对端中间有丢包
这个case是经过了负载均衡转发,所以源和目的地址对不上,还有Fin和Reset的行为对不上。不过中间的传输是没有问题的,可以通过两边的行为,典型的一边一直再发,另一边收不到,所以一直告诉对方丢了中间的包,直到重传导致连接断开
case 2:
和case1一样,wireshark显示长度为1514的包重传,导致连接中断
case 3:
以下这种情况收到icmp error以后,修正自己的发包大小
查到中间路径返回的icmp error ,告诉他下一跳的MTU是 1452,这样发送端调整发送大小,服务正常进行下去。
case 4:
udp包测试最大MTU,udp没有分片的情况,因为UDP协议本身就是无状态的,所以udp发大包,会直接丢弃。
udp模拟,nc是很好的工具
client端运行,nc serverip port
server端运行 nc -l -u port
ping -M do www.baidu.com -s 1472
可以在server直观的看到是否收到对端发来的包
三、后记
想要探测沿途的mtu,尽管大多数的系统不支持路径MTU发现功能,但可以很容易地修改traceroute程序,用它来确定路径MTU。要做的是发送分组,并设置“不可分片”标志比特。发送的第一个分组的长度正好与出口MTU相等,每次收到ICMP“不能分片”差错时就减小分组的长度。如果路由器发送的ICMP差错报文是新格式,包含出口的MTU,那么就用该MTU值来发送,否则就用下一个最小的MTU值来发送。正如RFC1191[Mogul and Deering 1990]声明的那样,MTU值的个数是有限的,因此在我们的程序中有一些由近似值构成的表,取下一个最小MTU值来发送。