此文已由作者徐城利授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
在上一篇中已经介绍了一些基础的网络知识,而这一篇中我们将对一些实际应用中比较常见的问题进行诊断。
网络连通性是平时最基本的问题,也是大部分网络问题中首先需要确认的。 最简单也是每个人都知道的工具ping,虽然这是个很基本的命令,但还是能给我们提供不少有用的信息。
Uknown host: 这个错误表示域名解析错误,需要检查DNS配置。
Network unreachable: 这个错误表示是二层网络不通,可能没有正确配置网络、网线不对、交换机配置错误等原因。
Operation permission denied: 这个错误一般表示包被自己的内核丢掉,需检查本地的防火墙规则,内核是不是有异常,如conntrack表满,arp缓存满,socket内存用尽等。
Timeout: 三层不通,一般需要分析整个路由路径。
注意:有些网络设备或服务器禁掉了ICMP,有些设备在处理ICMP和处理转发的性能差很多,因此,ping的结果更多是作为一个参考,而非判断网络连通性和网络状态的绝对标准。
当发现域名解析出现问题时,可以先查看系统配置了解当前使用的nameserver,再检查nameserver是否可用,也可以直接通过nslookup或dig等命令查看当前系统的域名解析情况。
~$ nslookup yun.163.comServer: 10.180.0.223Address: 10.180.0.223#53Non-authoritative answer:Name: yun.163.comAddress: 223.252.208.251
如结果所示:本地用于解析的DNS服务器是10.180.0.223, yun.163.com这个域名指向了223.252.208.251这个IP。 如果系统默认的DNS解析出来的结果不对,也可以指定特定的nameserver,看结果是否一致:
~$ nslookup yun.163.com 114.114.114.114Server: 114.114.114.114Address: 114.114.114.114#53Non-authoritative answer:Name: yun.163.comAddress: 223.252.208.251
如果碰到二层网络不通,可能是本地方的配置问题,也可能是对端的问题,因此需要逐一排除:
使用ip link、ip address、ip route等命令检查本地的设备是否已经正确配置(例如网卡状态为UP、Carrier状态正常、正确配置了IP,到目标地址的路由正确)
测试同个二层网络内的其他IP地址是否可以访问
可以使用arping等工作在更下层的工具,适合IP被防火墙屏蔽等情况
~$ sudo arping -I eth0.100 10.180.0.24ARPING 10.180.0.24 from 10.180.0.86 eth0.100Unicast reply from 10.180.0.24 [34:40:B5:DB:35:B0] 0.658msUnicast reply from 10.180.0.24 [34:40:B5:DB:35:B0] 0.576msUnicast reply from 10.180.0.24 [34:40:B5:DB:35:B0] 0.575msUnicast reply from 10.180.0.24 [34:40:B5:DB:35:B0] 0.588ms
此外,arping还能用于检测是否在冲突IP
~$ sudo arping -D -I eth0.100 10.180.0.24ARPING 10.180.0.24 from 0.0.0.0 eth0.100Unicast reply from 10.180.0.24 [34:40:B5:DB:35:B0] 0.597msSent 1 probes (1 broadcast(s))Received 1 response(s)
及用于更新交换机上或其他服务器上的ARP缓存
~$ sudo arping -U -c3 -I eth0.100 10.180.0.86ARPING 10.180.0.86 from 10.180.0.86 eth0.100Sent 3 probes (3 broadcast(s)) Received 0 response(s)
当三层网络不通时,可以按以下步骤来:
同样使用ip addresss和ip route等命令检查本地的IP配置及到目标的路由
根据路由,检查网关是否可达
可以使用mtr、traceroute等工具获取更多的信息
mtr集成了traceroute和ping的功能,是一个比较方便的诊断辅助工具,Windows下也有port实现,如WinMtr
~$ mtr -c4 -r 114.114.114.114HOST: 10-180-0-86 Loss% Snt Last Avg Best Wrst StDev 1.|-- 115.236.124.1 25.0% 4 3.8 3.0 0.3 4.7 2.3 2.|-- ??? 100.0 4 0.0 0.0 0.0 0.0 0.0 3.|-- 61.164.31.49 0.0% 4 3.2 1.4 0.7 3.2 1.2 4.|-- 61.164.29.9 25.0% 4 1.6 1.3 1.2 1.6 0.3 5.|-- 202.97.84.74 0.0% 4 8.4 6.5 5.4 8.4 1.3 6.|-- 218.2.182.74 0.0% 4 9.3 9.5 7.7 10.6 1.3 7.|-- 58.213.224.170 0.0% 4 7.2 7.4 7.2 8.0 0.4 8.|-- public1.114dns.com 0.0% 4 8.4 8.5 8.4 8.5 0.0
如图所示,mtr基本列出了整个网络路径上每一跳的丢包率、RTT等信息,类似于用traceroute获取转发路径上的每一跳,并逐一去ping的效果。 大家可能注意到上面的结果中,中间节点的丢包率反而被后面的高,这也是之前提到的,网络设备在处理ICMP的性能不等同于处理转发的性能,有些甚至完全禁用了ICMP。因此traceroute等工具支持多种网络协议,可以配合使用,Windows下的tracert只支持单协议。
~$ sudo traceroute -I 114.114.114.114 traceroute to 114.114.114.114 (114.114.114.114), 30 hops max, 60 byte packets 1 115.236.124.1 (115.236.124.1) 0.337 ms 0.374 ms 0.439 ms 2 * * * 3 61.164.31.49 (61.164.31.49) 1.019 ms 1.036 ms 1.059 ms 4 * * * 5 202.97.84.74 (202.97.84.74) 8.278 ms 8.312 ms 8.305 ms 6 218.2.182.74 (218.2.182.74) 11.171 ms 9.872 ms 9.841 ms 7 58.213.224.170 (58.213.224.170) 7.328 ms 7.749 ms 8.156 ms 8 public1.114dns.com (114.114.114.114) 8.357 ms 8.426 ms 8.425 ms ~$ sudo traceroute -T 114.114.114.114 traceroute to 114.114.114.114 (114.114.114.114), 30 hops max, 60 byte packets 1 115.236.124.1 (115.236.124.1) 0.361 ms 0.406 ms 0.464 ms 2 * * * 3 * * 61.164.31.29 (61.164.31.29) 4.580 ms 4 * * 61.164.31.229 (61.164.31.229) 3.135 ms 5 202.97.41.249 (202.97.41.249) 9.948 ms 202.97.68.237 (202.97.68.237) 10.384 ms 202.97.84.74 (202.97.84.74) 6.072 ms 6 218.2.134.74 (218.2.134.74) 7.191 ms 218.2.182.34 (218.2.182.34) 9.558 ms 221.231.191.170 (221.231.191.170) 10.637 ms 7 * * * 8 * * * 9 * * * 10 * * *
如图,使用不同协议的结果是不同的。
如果整个网络路径上所有或部分节点可控,也可以使用抓包的方式来缩小查找的范围(网络抓包分析的相关内容将在后续文章讨论)。
当碰到服务无法访问时,也可以根据返回的错误进行初步判断,各个错误对应的诊断过程完全是不同的。
当看到这个错误时,首先表示网络连通性没有问题,一般是服务没有监听:
检查要访问的目标地址是否正确,如写错IP、域名解析错误、连错端口等
检查服务是否监听了正确的地址,例如一些应用只监听了127.0.0.1,就无法被远程访问。这些信息都可以通过上篇文章提过的ss或netstate等命令获取
连接超时的情况更加复杂点,不过也有一定的检查步骤:
先通过ping等方式检查目标地址是否可达,如不可达则参考前面网络连通性的诊断方法。
如果是TCP应用,通过telnet等检查指定端口是否可以建立TCP连接,如果无法连接,重点检查服务端是否有防火墙规则之类的限制。
如果可以telnet,但还是无法建立连接,一般涉及到了具体的应用实现,这时就要靠抓包、日志等方法结合应用实现、协议实现等业务知识来进行分析,已经超出这篇文章的范畴了。
当服务器碰到无法建立新连接等问题时,关注下socket的统计信息有时能发现一些有用的线索:
~$ sudo ss -s Total: 138 (kernel 206) TCP: 24 (estab 4, closed 5, orphaned 0, synrecv 0, timewait 3/0), ports 18 Transport Total IP IPv6 * 206 - - RAW 0 0 0 UDP 14 11 3 TCP 19 13 6 INET 33 24 9 FRAG 0 0 0
如果看到大量的synrecv、timewait、close-wait、orphaned等,就值得关注:
大量的syn_recv:应用已经无法接收新的请求,有可能是应用服务本身问题,也有可能是被类似syn flood攻击。
大量的close_wait: 如果系统上出现大量的这种状态,一般是应用程序的bug,没有正确处理远端的断开连接请求。
大量的time_wait: 在访问量比较大的应用服务器上一定量的time_wait是正常的,但如果一直往上增加,可能是有客户端不断的新建、断开连接,可以通过设置内核参数,减小time_wait时间,或允许重用。
在分析socket问题时,熟悉TCP各个状态之类的转换非常重要,网上也有很多图例可以参考。
有些用户碰到性能问题时,直接说:“我们的并发数上不去,一定是你们网络的问题,得给我解决!” 碰到这样的用户,有时确实也令人无奈。何不在把责任撇清前先自己先做一个初步的分析呢? 假设服务器A(10.0.1.2)上一个应用调用了服务器B(10.0.1.3)上的另外一个服务(端口8080),在A中发现调用B的服务时并发数不够,那怎么才能知道是应用程序本身的问题,还是底层网络的问题呢?其实在前一篇已经提到过。
在A和B上检查socket的状态
A:~$ sudo ss state established dst :8080 Netid Recv-Q Send-Q Local Address:Port Peer Address:Port DIAG answers 22 tcp 0 0 10.0.1.2:46728 10.0.1.3:8080 B:~$ sudo ss state established dst 10.0.1.2 and src :8080 Netid Recv-Q Send-Q Local Address:Port Peer Address:Port DIAG answers 22 tcp 0 0 10.0.1.3:8080 10.0.1.2:46728
我们可以通过两端socket收发队列中的数据进行判断:
当A的Send-Q中数据堆积而B的Recv-Q中数据为0时,一般是A-B之间的网络问题
当A的Send-Q和B的Recv-Q中的数据同时累积时,一般是B服务的性能问题
当A的Recv-Q中数据堆积时,一般是A本身的性能问题
如果所有的队列都为0,那还是表示网络没有成为瓶颈
如果确定是网络问题,再进一步对整个网络路径进行排查,如某个节点上带宽用完、CPU耗尽、丢包等。
这一篇文章中,我们总结了一些常见的网络问题及诊断方法。通过这些方法基本上可以排除不少日常的网络问题,当然,网络本身牵涉到不少复杂的情况,有时无法只通过一些简单的工具就能了解所有的情况,必须要求我们对网络上的包的内容进行分析,这将是我们下一篇的内容,敬请关注。
网易云免费体验馆,0成本体验20+款云产品!
更多网易技术、产品、运营经验分享请点击。
相关文章:
【推荐】 测试角度的并发和幂等问题总结
【推荐】 聊一聊数据分析师这个职业
【推荐】 分布式存储系统可靠性系列一:如何估算