0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

服务器ping不通但是http能请求成功是什么原因

小林coding 来源:小白debug 2024-10-23 09:23 次阅读

以下文章来源于小白debug,作者小白

大家好,我是小林。

昨天分享了一篇腾讯后端面经:「好难!腾讯面试体验已结束」,里面就有个问题:

服务器ping不通但是http能请求成功,会出现这种情况吗?什么原因造成的?

那么,今天就详细聊聊这个问题。

正文

平时,我们想要知道,自己的机器到目的机器之间,网络通不通,一般会执行ping命令

一般对于状况良好的网络来说,你能看到它对应的loss丢包率为0%,也就是所谓的能ping通。如果看到丢包率100%,也就是ping不通

4c52a26c-9030-11ef-a511-92fbcf53809c.pngping正常 4c803d8a-9030-11ef-a511-92fbcf53809c.pngping不通

那么问题来了,假设我能ping通某台机器,那这时候如果我改用TCP协议去发数据到目的机器,也一定能通吗?

或者换个问法,ping和tcp协议走的网络路径是一样的吗?

这时候第一反应就是不一定,因为ping完之后中间链路里的某个路由器可能会挂了(断电了),再用TCP去连就会走别的路径。

也没错。但假设,中间链路没发生任何变化呢?

我先直接说答案。

不一定,走的网络路径还是有可能是不同的。

今天就来聊聊为什么。

我之前写过一篇《断网了,还能ping通 127.0.0.1 吗?》,里面提到过ping数据包和tcp数据包的区别

4c9ad352-9030-11ef-a511-92fbcf53809c.pngping和TCP发消息的区别

我们知道网络是分层的,每一层都有对应协议。

4cb2d100-9030-11ef-a511-92fbcf53809c.png五层网络协议对应的消息体变化分析

而这网络层就像搭积木一样,上层协议都是基于下层协议搭出来的。

不管是ping(用了ICMP协议)还是tcp本质上都是基于网络层IP协议的数据包,而到了物理层,都是二进制01串,都走网卡发出去了。

如果网络环境没发生变化,目的地又一样,那按道理说他们走的网络路径应该是一样的,什么情况下会不同呢?

我们就从路由这个话题聊起吧。

网络路径

在我们的想象中,当我们想在两台机器之间传输数据。本机和目的机器之间会建立一条连接,像一条管道一样,数据从这头到那头。这条管道其实是我们为了方便理解而抽象出来的概念。

实际上,我们将数据包从本地网卡发出之后,会经过各种路由器(或者交换机,才能到达目的机器。

这些路由器数量众多,相互之间可以互连,连起来之后就像是一张大网,所以叫**"网络"**可以说是非常的形象。

4ccab46e-9030-11ef-a511-92fbcf53809c.png路由器构成的网络

考虑到交换机有的功能,路由器基本上都支持,所以我们这边只讨论路由器。

那么现在问题来了,路由器收到数据后,怎么知道应该走哪条路径,传给哪个路由器?

路径由什么决定?

在上面的那么大一张网络中,随便一个路由器都有可能走任何一个路径,将数据发到另外一个路由器上,

但路由和路由之间距离,带宽啥的可能都不同。

于是就很需要知道,两点之间走哪条路才是最优路径

于是问题就变成了这样一个图状结构。每条边都带有成本或权重,算这上面任意两点的最短距离

4ce39b8c-9030-11ef-a511-92fbcf53809c.png路由器和Dijkstra

这时候想必大家回忆压不住要上来了。

这题我熟,这就是大学时候刷的Dijkstra算法。菊花厂的OJ笔试题集里也经常出现,现在终于明白为什么他们家的笔试题里图类题目比别的大厂貌似要多一些了吧,因为菊花厂就是搞通信的,做路由器的老玩家了。

路由表的生成

基于Dijkstra算法,封装出了一个新的协议,OSPF协议Open Shortest Path First, 开放最短路径优先)。

有了OSPF,路由器就得到了网络图里自己到其他点之间的最短距离,于是就知道了数据包要到某个点,该走哪条最优路径

将这些信息汇成一张表,也就是我们常说的路由表

路由表里记录了到什么IP需要走什么端口,以及走这条路径的成本(metric)。

可以通过 route 命令查看到。

4d06ff8c-9030-11ef-a511-92fbcf53809c.pngroute表

路由表决定数据包路径

数据包在发送的过程中,会在网络层加入目标地址IP

路由器会根据这个IP路由表去做匹配。

然后路由表,会告诉路由器,什么样的消息该转发到什么端口。

举个例子。

4d233b3e-9030-11ef-a511-92fbcf53809c.png通过路由表转发数据

假设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/24192.168.0.0/16都能匹配上,但明显前者匹配长度更长,所以最后会走 192.168.1.0/24对应的转发端口。

但如果两个表项的匹配长度都一样呢?

那就会看生成这个路由表项的协议是啥,选优先级高的,优先级越高也就是所谓的管理距离ADAdministrativeDistance)越小。比如说优先选手动配的静态(static)路由,次优选OSPF动态学习过来的表项。

如果还是相同,就看度量值metrics,其实也就是路径成本cost,成本越小,越容易被选中。

路由器能选的路线有很多,但按道理,最优的只有"一条",所以到这里为止,我们都可以认为,对于同一个目的地,ping和TCP走的路径是相同的。

但是。

如果连路径成本都一样呢?也就是说有多条最优路径呢。

那就都用

这也就是所谓的等价多路径,ECMPEqual Cost MultiPath)。

我们可以通过traceroute看下链路是否存在等价多路径的情况。

4d45e274-9030-11ef-a511-92fbcf53809c.png图片

可以看到,中间某几行,有好几个IP,也就是说这一跳里同时可以选好几个目的机器,说明这段路径支持ECMP

ECMP有什么用

利用等价多路径,我们可以增加链路带宽

举个例子。

4d628b2c-9030-11ef-a511-92fbcf53809c.png没有ECMP时只能选择某一条路径

从A点到B点,如果这两条路径成本不同,带宽都是1千兆。那数据包肯定就选成本低的那条路了,如果这条路出故障了,就走下面那条路。但不管怎么样,同一时间,只用到了一条路径。另外一条闲置就有些浪费了,有没有办法可以利用起来呢?

有,将它们两条路径的成本设置成一样,那它们就成了等价路由,然后中间的路由器开启ECMP特性,就可以同时利用这两条链路了。带宽就从原来的1千兆变成了2千兆。数据就可以在两条路径中随意选择了。

4d8c7d6a-9030-11ef-a511-92fbcf53809c.png利用ECMP可以同时使用两条链路

但这也带来了另外一个问题。加剧了数据包乱序

原来我只使用一条网络路径,数据依次发出,如无意外,也是依次到达。

现在两个数据包走两条路径,先发的数据包可能后到。这就乱序了。

那么问题又又来了。

乱序会有什么问题?

对于我们最最最常使用的TCP协议来说,它是个可靠性网络的协议,这里提到的可靠,不仅是保证数据要能送到目的地,还要保证数据顺序要跟原来发送端的一样。

实现也很简单,TCP为每个数据包(segment)做上编号。数据到了接收端后,根据数据包编号发现是乱序数据包,就会扔到乱序队列中对数据包进行排序。如果前面的数据包还没到,哪怕后面的数据包先到了,也得在乱序队列中一直等,到齐后才能被上层拿到。

举个例子,发送端发出三个数据包,编号1,2,3,假设在传输层2和3先到了,1还没到。那此时应用层是没办法拿到2和3的数据包的,必须得等1来了之后,应用层才能一次性拿到这三个包。因为这三个包原来可能表示的是一个完整的消息,少了1, 那么消息就不完整,应用层拿到了也毫无意义。

像这种,由于前面的数据丢失导致后面的数据没办法及时给到应用层的现象,就是我们常说的TCP队头阻塞

4dac7c5a-9030-11ef-a511-92fbcf53809c.png乱序队列等待数据包的到来

乱序发生时2和3需要待在乱序队列中,而乱序队列其实用的也是接收缓冲区的内存,而接收缓冲区是有大小限制的。通过下面的命令可以看到接收缓冲区的大小。

#查看接收缓冲区
$sysctlnet.ipv4.tcp_rmem
net.ipv4.tcp_rmem=4096(min)87380(default)6291456(max)
#缓冲区会在min和max之间动态调整

乱序的情况越多,接收缓冲区的内存就被占用的越多,对应的接收窗口就会变小,那正常能收的数据就变少了,网络吞吐就变差了,也就是性能变差了。

因此,我们需要尽量保证所有同一个TCP连接下的所有TCP包都走相同路径,这样才能最大程度避免丢包

ECMP的路径选择策略

当初开启ECMP就是为了提升性能,现在反而加重了乱序,降低了TCP传输性能。

这怎么能忍。

为了解决这个问题,我们需要有一个合理的路径选择策略。为了避免同一个连接里的数据包乱序,我们需要保证同一个连接里的数据包,都走同样的路径。

这好办。我们可以通过连接的五元组(发送方的IP端口,接收方的IP端口,以及通信协议)信息定位到唯一一条连接。

4dc52e6c-9030-11ef-a511-92fbcf53809c.png五元组

然后对五元组信息生成哈希键,让同一个哈希键的数据走同一条路径,问题就完美解决了。

4def8162-9030-11ef-a511-92fbcf53809c.png五元组映射成hash键 4e04642e-9030-11ef-a511-92fbcf53809c.png根据五元组选择ECMP路径

TCP和Ping走的网络路径一样吗

现在我们回到文章开头的问题。

对于同样的发送端和接收端,TCP和Ping走的网络路径一样吗?

不一定一样,因为五元组里的信息里有一项是通信协议。ping用的是ICMP协议,跟TCP协议不同,并且ping不需要用到端口,所以五元组不同,生成的哈希键不同,通过ECMP选择到的路径也可能不同。

4e64e27c-9030-11ef-a511-92fbcf53809c.pngTCP和ping的五元组差异

同样都用TCP协议,数据包走的网络路径一样吗

还是同样的发送端和接收端,同样是TCP协议,不同TCP连接走的网络路径是一样的吗?

跟上面的问题一样,其实还是五元组的问题,同样都是TCP协议,对于同样的发送端和接收端,他们的IP和接收端的端口肯定是一样的,但发送方的端口是可以随时变化的,因此通过ECMP走的路径也可能不同。

4e89b26e-9030-11ef-a511-92fbcf53809c.png不同TCP连接的五元组差异

但问题又来了。

我知道这个有什么用呢?我做业务开发,又没有设置网络路由的权限。

利用这个知识点排查问题

对于业务开发,这绝对不是个没用的知识点。

如果某天,你发现,你能ping通目的机器,但用TCP去连,却偶尔连不上目的机器。而且两端机器都挺空闲,没什么性能上的瓶颈。实在走投无路了。

你就可以想想,会不会是网络中用到了ECMP,其中一条链路有问题导致的。

4ea1bcf6-9030-11ef-a511-92fbcf53809c.pngping能成功但部分TCP连接失败

排查方法也很简单。

你是知道本机的IP以及目的机器的IP和端口号的,也知道自己用的是TCP连接。

只要你在报错的时候打印下错误信息,你就知道了发送端的端口号了。

这样五元组是啥你就知道了。

下一步就是指定发送端的端口号重新发起TCP请求,同样的五元组,走同样的路径,按理说如果链路有问题,就肯定会复现。

如果不想改自己的代码,你可以用nc命令指定客户端端口看下能不能正常建立TCP连接。

nc-p6666baidu.com80

-p 6666是指定发出请求的客户端端口是6666,后面跟着的是连接的域名80端口

4ebc39aa-9030-11ef-a511-92fbcf53809c.png通过nc成功建立tcp连接

假设用了6666端口的五元组去连接总是失败,改用6667或其他端口却能成功,你可以带着这个信息去找找负责网络的同事。

总结

路由器可以通过OSPF协议生成路由表,利用数据包里的IP地址去跟路由表做匹配,选择最优路径后进行转发。

当路由表一个都匹配不上时会走默认网关。当匹配上多个的时候,会先看匹配长度,如果一样就看管理距离,还一样就看路径成本。如果连路径成本都一样,那等价路径。如果路由开启了ECMP,那就可以同时利用这几条路径做传输。

ECMP可以提高链路带宽,同时利用五元组做哈希键进行路径选择,保证了同一条连接的数据包走同一条路径,减少了乱序的情况。

可以通过traceroute命令查看到链路上是否有用到ECMP的情况。

开启了ECMP的网络链路中,TCP和ping命令可能走的路径不同,甚至同样是TCP,不同连接之间,走的路径也不同,因此出现了连接时好时坏的问题,实在是走投无路了,可以考虑下是不是跟ECMP有关。

当然,遇到问题多怀疑自己,要相信绝大部分时候真的跟ECMP无关

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • TCP
    TCP
    +关注

    关注

    8

    文章

    1353

    浏览量

    79055
  • Ping
    +关注

    关注

    0

    文章

    69

    浏览量

    15974
  • 命令
    +关注

    关注

    5

    文章

    683

    浏览量

    22011
  • TCP协议
    +关注

    关注

    1

    文章

    91

    浏览量

    12070

原文标题:腾讯一面:能ping通,TCP就一定能连通吗?

文章出处:【微信号:小林coding,微信公众号:小林coding】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    dhcp服务器

    服务设置完了后,客户电脑上得到服务器分配的ip地址但是不通什么原因啊!请高手指点,联系QQ279282417
    发表于 02-14 00:39

    在部署共享变量时 可以找到服务器但是找不到服务器中的共享变量,这是什么原因呢?

    请教一下在部署共享变量时 可以找到服务器但是找不到服务器中的共享变量,这是什么原因呢?可以指导一下吗共享变量的部署问题:
    发表于 05-21 15:40

    dm8148网络uboot环境下ping同,进入系统却ping不通??

    不知道什么原因造成的),在文件系统内配置与主机在同一网断,但是不能ping通主机; 我的疑问是uboot下使用ping 的时候显示active;并且tftp也
    发表于 06-23 05:33

    LPC1788TCP服务器ping成功

    LPC1788的UDP通信没有问题,可以ping成功,正常收发数据,但是下载了咱们论坛里的悍马版LPC1788的TCP服务器程序,就是ping
    发表于 07-20 17:31

    为什么ping不通还能烧写程序?

    大家好,我是一个菜鸟,刚学2440,我用CRT ping不通PC机,却能顺利烧写到nanflash,这是什么原因,怎样解决ping不通
    发表于 06-17 22:59

    请求信号量能请求成功吗?

    OS_EVENT * RandomSem; OSSemPend(RandomSem, 0, &err);LED1_ON(RED);//点灯这样写有个地方不明白,这是请求信号量,能不能请求成功,没有判断,为什么可以这样写LED1_ON(RED).
    发表于 08-20 04:35

    使用CH32V307+WCHNET实现webserver服务http请求无法访问怎么解决?

    使用CH32V307+ WCHNET 实现 webserver 服务,加电后HTTP请求可以正常访问,ping平通,
    发表于 09-14 07:06

    请问CH32V307 ping正常但是http请求少部分正常大部分请求超时是为什么?

    请问 CH32V307ping正常 但是 http请求少部分正常大部分请求超时 ,用的是netlib,这个会是
    发表于 09-15 07:32

    ESP32 Web服务器可以向外部Rest API发起HTTP请求吗?

    服务器 API 也可以发起/发出请求?3)传入和传出请求的流量是否由同一个端口处理(出于端口转发的原因)?举个例子,考虑一下自动化中使用的 ESP32,它有自己的 WEB UI,可以
    发表于 03-01 06:22

    Java编程:发送HTTP请求服务器

    当Java程序需要向服务器发送请求或读取服务器数据时,使用URLConnection类是比较好的选择。URLConnection类封装了与服务器互动操作的方法,通过它可以建立与
    的头像 发表于 07-01 09:59 3077次阅读
    Java编程:发送<b class='flag-5'>HTTP</b><b class='flag-5'>请求</b>到<b class='flag-5'>服务器</b>

    MCU没有响应服务器请求,NodeMCU HTTP服务器停止响应

    我正在尝试使用NodeMCU创建一个简单的HTTP服务器 . 我启动nodeMCU然后将其连接到wifi,然后运行下面的程序 . 我可以从浏览连接到服务器 . 如果我继续重新加载页面
    发表于 10-25 18:21 11次下载
    MCU没有响应<b class='flag-5'>服务器</b><b class='flag-5'>请求</b>,NodeMCU <b class='flag-5'>HTTP</b><b class='flag-5'>服务器</b>停止响应

    【笔记】ping不通原因有那些?

    Ping命令无法成功访问目标主机时,可能存在多种原因。以下是一些常见的导致Ping不通的问题,并对每个问题进行了分析和解释:1.
    的头像 发表于 05-30 17:24 2.2w次阅读
    【笔记】<b class='flag-5'>ping</b><b class='flag-5'>不通</b>的<b class='flag-5'>原因</b>有那些?

    使用NS1串口服务器HTTP模式上传服务器数据

    HTTP协议工作于客户端-服务端架构之上。浏览作为HTTP客户端通过URL向HTTP服务端即W
    的头像 发表于 08-30 12:36 314次阅读
    使用NS1串口<b class='flag-5'>服务器</b><b class='flag-5'>HTTP</b>模式上传<b class='flag-5'>服务器</b>数据

    服务器之间ping不通原因

    服务器之间ping不通可能由多种原因造成,以下是一些常见的原因及其解决方法: 一、物理连接问题 网线问题 : 网线未插好或松动,导致
    的头像 发表于 10-14 15:02 2289次阅读

    局域网ping不通原因有哪些

    使用 ping 命令测试两台计算机之间的连接时,如果 ping 不通,可能存在多种原因。以下是一些可能导致局域网 ping
    的头像 发表于 10-14 15:03 3801次阅读