《深入分析 Linux 网络丢包问题.docx》由会员分享,可在线阅读,更多相关《深入分析 Linux 网络丢包问题.docx(11页珍藏版)》请在课桌文档上搜索。
1、所谓丢包,足指在网络数据的收发过程中,由于种种原因,数据包还没传输到应用程序中,就被丢作了.这些被丢弃包的数景,除以总的传输包数,也就是我们常说的丢包率。丢包率是网络性能中最核心的指标之一。丢包通常会带来严重的性能下降,特别是对TCp来说,丢包通常意味着网络拥塞和电传进而还会导致网络延迟增大、吞吐降低.一、哪里可能丢包接下来,我就以最常用的反向代理服务器Nginx为例,带你一起看看如何分析网络丢包的问题,执行下面的hping3命令,进一步验证Nginx是不是可以正常访问。这里我没有使用Ping,是因为ping基于ICMP协议,而Nginx使用的是TCP协议.110packetstransmit
2、ted,5packetsreceived,5%packetlossround-tripmin/avg/nax三3.0/609.7/3027.2ns从hping3的输出中,我们可以发现,发送了10个请求包,却只收到了5个回豆,50%的包都丢了.再观察每个请求的RTT可以发现,RTT也有非常大的波动变化,小的时候只有3ms,而大的时候则有3s根据这些输出,我们基本能判断,已经发生了丢包现象,可以猜测,3s的RTT,很可能是因为丢包后至传导致的.那到底是哪里发生了丢包呢?排查之前,我们可以回忆一下1.inux的网络收发流程,先从理论上分析,哪里有可能会发生丢包.你不妨拿出手边的笔和纸,边回忆边在纸上
3、梳理,思考清楚再继续下面的内容.在这里,为了帮你理解网络丢包的原理,我画了一张图,你可以保存并打印出来使用从图中你可以看出,可能发生丢包的位置,实际上贯穿了整个网络协议栈.换句话说,全程都有丢包的可能. 在两台VM连接之间,可能会发生传输失败的错误,比如网络拥塞、线路错误等; 在网卡收包后,环形缓冲区可能会因为溢出而丢包; 在腌路屋,可能会因为网络帧校蛉失败、QoS等而丢包; 在IP展,可能会因为路由失败、组包大小超过MTU等而丢包; 在传输屣,可能会因为端口未监听、资源占用超过内核限制等而丢包; 在套接字层,可能会因为套接字缓冲区溢出而丢包; 在应用层,可能会因为应用程序异常而丢包; 此外,
4、如果配背了iptables规则,这些网络包也可能因为iptables过谑规则而丢包当然,上面这些何瓦还有可能同时发生在通信的两台机器中.不过,由于我们没对YM2做任何修改,并旦VM2也只运行了一个最简单的hping3命令,这儿不妨假设它是没有问题的。为了简化整个扑杳过程,我们还可以进一步假设,VMl的网络和内核配置也没问题接卜.来,就可以从协议核中,逐层排查丢包问题。链路层当链路层由于缓冲区溢出等原因导致网卡丢包时,1.inux会在网卡收发数据的统计信息中记录下收发错误的次数.可以通过ethtool或者netstat,来百看网卡的丢包记录。3SRX-OK.RX-ERR,RX-DRP,RX-OV
5、R,分别表示接收时的总包数、总错误数、进入RingBuffer后因其他原因(如内存不足)导致的丢包数以及RingBuffer溢出导致的丢包数.TX-OK.TX-ERR,TX-DRP.TX-OVR也代表类似的含义,只不过是指发送时对应的各个指标.这里我们没有发现任何错误,说明虚拟网卡没有丢包.不过要注意,如果用tc等工具配置了QoS,那么tc规则导致的丢包,就不会包含在网卡的统计信息中。所以接下来,我们还要检直一下eth上是否配置了tc规则,并查看有没有丢包.添加-S选项,以输出统计信息:disct80drootrefc11t2limit100loss3可以看到,eth上配百了一个网络模拟排队规
6、则(qdiscnetem),并且配置了丢包率为30%(loss30%).再看后面的统计信息,发送了8个包,但是丢了4个。看来应该就是这里导致Nginx回复的响应包被netem模块给丢了.既然发现了问题,解决方法也很简单,直接删掉netem模块就可以了。执行下面的命令,删除tc中的netem模块:IOiscueiQeVx11vrooxeeJiloss删除后,由新执行之前的hping3命令,看看现在还有没有问题:不幸的是,从hping3的输出中可以看到还是50%的丢包,R11的波动也仍旧很大,从3ms到Is.品然,问题还是没解决,丢包还在继续发生不过,既然处路层已经持查完了,我们就继续向上层分析,
7、籽右网洛层和传输层有没有问题.三、网络层和传输层在网络层和传输层中,引发丢包的因素非常多.不过,其实想确认是否丢包,是非常简单的事,因为IinUX已经为我们提供了各个协议的收发汇总情况,执行netstat-s命令,可以看到协议的收发汇总,以及错误信息:01CMPmessagesreceived/,(剑的ICNP2_llICMPincICMPoutputhiactiveconnectionopeninm:.assiveconnectionopeninco11n1connectionsestablished25segmentsreceivedI4segmentsretransmitted低传找文b
8、adsegmentsreceivedresetssent11reserruedVedforei,:.:.、:rHIfcKr(.acketheadersprl,255.255.5.3958:Fla1,nop,TSval25093791ecr48680541,no.sack4:40:03.S89352IP10.255.25S.5.39S8172.17.0.tionsnop,nop.TSVaI486800541ecr2509376001tions从tcpdump的输出中,我们就可以看到:前三个包是正常的TCP三次握手,这没问题;但第四个包却是在3眇以后了,并且还是客户端(VM2)发送过来的FIN包,
9、说明客户端的连接关闭了根据curl设置的3秒超时选项,你应该能猜到,这是因为curl命令超时后退出了。用Wireshark的FlowGraph来表示,你可以更清甦地看到上面这个问题:Time192.168.0.2192.168.030Comment0.000000SYNQfSeq三00.0000340*OT7AAfSYN.ACKOVOASe三0Acka10.001976,17RACKOVOASq1Ackr13.000520FIN.ACKOVSeq三76Ack13.00054537446ACKOV80Seq1Ack1这里比较奇怪的是,我们并没有抓取到curl发来的HTTPGET请求.那究竟是网卡
10、丢包了,还是客户端就没发过来呢?可以由新执行netstat-i命令,确认一下网卡有没有丢包问题:kernelInterfacetablelIlface;RX-OKRXERRRX-ORPRXOVR*J三,4ERRX,DRrTXOVRaSS从netstat的城出中,你可以看到,接收丢包数(RX-DRP)是344,果然是在网卡接收时丢包了.不过问题也来了,为什么刚才用hping3时不丢包,现在换成GET就收不到了呢?还是那句话,遇到搞不懂的现象,不妨先去直查工具和方法的原理.我们可以对比一下这两个工具:hping3实际上只发送了SYN包;curl在发送SYN包后,还会发送HTTPGET诘求.HTTPGET本质上也是一个TCP包,但跟SYN包相比,它还携带了HTTPGET的数据。通过这个对比,你应该想到了,这可能是MTU配SS错误导致的。为什么呢?其实,仔细观察上面netstat的输出界面,第二列正是每个网卡的MTU值.eth的MTU只有100,而以太网的MTU默认值是1500,这个100就显得太小了.当然,MTU问地是很好解决的,把它改成1500就可以了.修改完成后,再切换到终端二中,再次执行curl命令,确认问迹是否真的解决了:html非常不容易呀,这次终于看到了熟悉的Nginx响应,说明丢包的问题终于彻底解决了.