通常我们想知道自己的机器和目的机器之间的网络被阻塞了,我们通常会执行Ping命令。
一般来说,对于一个状况良好的网络,你可以看到它对应的丢失丢包率是0%,也就是说可以Ping通如果看到丢包率是100%,说明Ping失败
Ping正常。
Ping不通
所以问题来了假设我可以Ping一台机器,那么如果我切换到TCP来发送数据到目的机器,它会工作吗
或者换个说法,Ping和tcp走的网络路径是一样的吗。
这时候第一反应就不一定了,因为Ping后中间链路的一个路由器可能会挂掉,然后用TCP连接会走另一条路。
也没错但是假设中间环节没有变化呢
我就说答案吧。
不一定,有可能是走的网络路径不一样。
今天就来说说为什么。
Ping和TCP消息传递的区别
我们知道网络是分层的,每一层都有相应的协议。
五层网络协议对应的消息体变化分析
这个网络层就像积木一样,上层协议基于下层协议。
Ping和tcp本质上都是基于网络层IP协议的包,但是到了物理层都是二进制01串,通过网卡发出去。
如果网络环境没变,目的地也一样,按理说他们走的网络路径应该是一样的什么情况下会不一样
先说路由的话题。
网络路径
在我们的想象中,当我们想要在两台机器之间传输数据时将在本地机器和目的机器之间建立连接,就像管道一样,数据从一端流向另一端这个管道实际上是一个抽象的概念,方便我们理解
事实上,我们从本地网卡发送数据包后,它会经过各种路由器,然后到达目的机器。
这些路由器数量众多,可以互相连接连接起来之后,它们就像一张大网,所以可以说网是一个非常生动的形象
路由器网络
考虑到交换机的所有功能,路由器基本都支持,这里只讨论路由器。
那么现在问题来了路由器收到数据后,怎么知道应该走哪条路径,发送给哪台路由器
是什么决定了路径。
在这样一个大型网络中,任何路由器都可以采用任何路径向另一台路由器发送数据。
但是路由之间的距离,带宽等等可能是不一样的。
所以非常有必要知道两点之间哪条路是最佳路径。
于是问题就变成了这样一个图形结构每条边都有一个成本或权重,计算它上面任意两点之间的最短距离
和Dijkstra路由器
这个时候,我想每个人的回忆都会涌上来。
这个问题我比较熟悉这是我大学时候刷的Dijkstra算法菊花的OJ笔测书也频频出现
路由表的生成
基于Dijkstra算法,封装了一种新的协议OSPF。
通过OSPF,路由器可以获得自己与网络图中其它点之间的最短距离,因此它知道数据包到达某一点时应采用哪条最佳路径。
将这些信息组合成一张表,也就是我们常说的路由表。
在路由表中,它记录了到达哪个IP需要哪个端口,以及采用此路径的成本。
您可以通过route命令查看它。
表格路线
路由表决定数据包路径。
在发送数据包的过程中,目的IP会被添加到网络层。
路由器会将此IP与路由表匹配。
然后,路由表会告诉路由器什么样的消息应该被转发到哪个端口。
比如说。
通过路由表转发数据
假设A要给d发消息,也就是在192.168.0.105/24,会给192.168.1.11/24发一条消息。
然后a会将消息发送到路由器。
路由器知道目的IP192.168.1.11/24,将其与路由表进行匹配,发现192.168.1.0/24在e2端口,于是会从e2端口发送报文,最终将报文发送到目的机器。
当然,如果在路由表中找不到,就调用默认网关,也就是从端口e1发送到IP192.0.2.1,这个路由器的路由表不知道去哪了也许其他路由器有
路由表匹配规则
在上面的例子中,路由表中只有一项匹配,所以必须是它。
但是条条大路通罗马实际上,到达目的地肯定有很多路径
如果路由表中有很多条目匹配,你会怎么做。
如果多个路由项可以到达目的地,则优先选择匹配长度较长的路由项比如目的地是192.168.1.11,发现路由表中192.168.1.0/24和192.168.0.0/16都可以匹配,但显然前者的匹配长度更长,所以最后会取192.168.1.0/24对应的转发端口
但是如果两个条目的匹配长度相同呢。
这取决于生成该路由表条目的协议选择优先级高的那个优先级越高,所谓的管理距离就越小例如,由玩家动态匹配的静态路由是首选,由OSPF动态学习的条目是第二首选
如果还是一样,看度量,其实就是路径成本费用成本越小,越容易被选中
路由器可以选择多条路由,但原则上,只有一条是最好的到目前为止,我们都可以认为Ping和TCP采用相同的路径到达相同的目的地
但是...
如果连路径成本都一样呢也就是说,存在多条最优路径
那就全部用上。
这就是所谓的等效多径,ECMP。
我们可以使用traceroute来查看链路中是否存在等效的多路径。
大家可以看到,中间几行有几个IP,这意味着在这一跳可以同时选择几个目的机器,说明这条路径支持ECMP。
ECMP有什么用。
使用等效多路径,我们可以增加链路带宽。
比如说。
没有ECMP时,只能选择一条路径。
从A点到B点,如果两条路径开销不同,带宽是1千兆那么这个包必须选择成本低的那条路如果这条路走不通,就走下面这条路但无论如何,在同一时间,只有一个路径被使用另一个闲置的时候就浪费了有什么办法可以利用吗
是的,如果它们两条路径的开销设置相同,它们将成为等价路由,然后中间的路由器将打开ECMP功能,以同时使用两条链路带宽从1千兆变成了2千兆可以在两条路径中随机选择数据
使用ECMP,可以同时使用两个链接。
但这也带来了另一个问题加剧了数据包无序
本来我只用一条网络路径,数据是依次发出去的,不出意外的话也是依次到达。
现在两个包走两条路径,第一个包可能会晚一点到达这是不正常的
那么问题又来了。
无序有什么问题。
对于我们最常用的TCP协议,它是一个可靠的网络协议这里所说的可靠性,不仅仅是保证数据能够发送到目的地,还要保证数据序列与原发送方相同
实现也很简单TCP对每个数据包进行编号当数据到达接收端时,根据包号发现是乱序包,会将其丢入乱序队列对包进行排序如果前一个数据包还没有到达,即使后一个数据包先到达,也要在乱序队列中等待,直到到达,然后才能被上层拾取
例如,发送方发出三个数据包,编号为1,2和3假设传输层2和3先到达,但1还没有到达这时候应用层就拿不到2和3的数据包了它必须等待1的到来,然后应用层才能同时获得这三个数据包因为这三个包本来可能代表一个完整的消息,如果少了一个,那么这个消息就是不完整的,应用层得到它是没有意义的
像这样,由于前面的数据丢失,后面的数据无法及时发送到应用层的现象,就是我们常说的TCP队列头阻塞。
等待数据包到达的无序队列。
当出现乱序时,2和3需要留在乱序队列中,而乱序队列实际上使用的是接收缓冲区的内存,大小有限您可以通过以下命令查看接收缓冲区的大小
#检查接收缓冲区$ sysctlnet . IP v4 . TCP _ rmemnet . IP v4 . TCP _ rmem = 4096873806291456#缓冲区将在最小值和最大值之间动态调整。
乱序情况越多,接收缓冲区占用的内存就越多,对应的接收窗口就越小,这样正常可接收的数据就越少,网络吞吐量就越差,也就是性能越差。
所以我们需要尽量保证同一TCP连接下的所有TCP包都走同一条路径,最大程度的避免丢包。
ECMP的路径选择策略
当初启动ECMP是为了提高性能,现在却加重了无序,降低了TCP传输性能。
这怎么能容忍。
要解决这个问题,我们需要一个合理的路径选择策略为了避免同一连接中数据包的无序,我们需要确保同一连接中的所有数据包都采用相同的路径
这很好办我们可以通过连接的五元组信息来定位唯一连接
五倍的
然后为五元组信息生成一个哈希键,让哈希键相同的数据走同一条路,问题就完美解决了。
五个元组被映射成散列键。
根据五元组选择ECMP路径
TCP和Ping的网络路径一样吗。
现在我们回到文章开头的问题。
对于同一个发送方和接收方,TCP和Ping是否采用相同的网络路径。
肯定是不一样的,因为五元组中有一条信息是通信协议Ping使用ICMP协议,与TCP协议不同,Ping不需要端口,所以不同的五元组,不同的生成哈希键,通过ECMP选择不同的路径
TCP和Ping之间的五元组差异
使用相同的TCP协议数据包是否采用相同的网络路径
还是一样的发送方和接收方,一样的TCP协议不同TCP连接采用的网络路径是否相同
和上面的问题一样,其实是一个五重问题它也是一种TCP协议对于同一个发送方和接收方,它们的IP和接收方端口必须相同,但是发送方的端口可以随时改变,因此通过ECMP的路径也可能不同
不同TCP连接的五元组差异
但是问题又来了。
知道这个有什么用我是搞业务拓展的,但是没有权限设置网络路由
使用该知识点解决问题。
对于业务拓展来说,这绝对不是一个没用的知识点。
如果有一天,你发现可以Ping通目的机器,但是用TCP连接,却偶尔连不上目的机器而且两端的机器都挺闲的,不存在性能瓶颈没有出路了
你可以考虑一下会不会是网络中使用了ECMP,某个环节出现了问题
Ping成功,但某些TCP连接失败。
筛选方法也很简单。
您知道这台机器的IP和目的机器的IP和端口号,并且您知道您正在使用TCP连接。
只要在报错的时候打印错误信息,就知道发件人的端口号了。
那你就知道什么是五倍子了。
下一步是指定发送方的端口号重新发起TCP请求,同样的五元组,走同样的路径按理说,如果链接有问题,肯定会重现
如果不想修改自己的代码,可以用nc命令指定客户端端口,看看TCP连接能否正常建立。
—p 6666是指定请求客户端的端口是6666,后面是连接的域名和端口80。
通过nc成功建立了Tcp连接
假设你用端口6666的五元组总是连接失败,但是用端口6667或者其他端口都可以成功你可以带着这些信息去找你负责网络的同事
摘要
路由器可以通过OSPF协议生成路由表,使用数据包中的IP地址来匹配路由表,然后选择最佳路径进行转发。
当没有匹配的路由表时,将使用默认网关匹配多个时,我们会先看匹配长度,如果相同,我们会看管理距离,如果相同,我们会看路径开销如果连路径开销都相同,那么等价路径如果打开ECMP进行路由,这些路径可以同时用于传输
ECMP可以提高链路带宽,同时使用五元组作为哈希键进行路径选择,保证了相同连接的数据包走相同的路径,减少了乱序。
您可以通过traceroute命令检查链路上是否使用了ECMP。
在ECMP开启的网络链路中,TCP和Ping命令可能会走不同的路径,甚至是同一个TCP,不同连接走的路径也不一样,所以存在连接时好时坏的问题这是真的绝望,所以考虑它是否与ECMP有关
当然,遇到问题的时候要怀疑自己,要相信大多数时候真的与ECMP无关。
参考数据
网络故障排除案例课程—极客时间