精华内容
下载资源
问答
  • 当网络有问题,首先我们会进行ping命令,所谓网络丢包是我们在使用ping命令(检测某个系统能否正常运行)对目的站进行询问时,数据包由于各种原因在信道中丢失现象。测试是否丢包,可以使用命令:ping -...
    在做弱电项目中,我们经常会出现网络比较卡、监控有几路画面不显示、网络时正常,时不正常等问题,这些故障大部分情况下是跟网络丢包有关,今天我们来看下,网络丢包怎么办,常见故障分析及处理方式。

    当网络有问题,首先我们会进行ping命令,所谓网络丢包是我们在使用ping命令(检测某个系统能否正常运行)对目的站进行询问时,数据包由于各种原因在信道中丢失的现象。

    测试是否丢包,可以使用命令:ping -t 192.168.16.1或者ping 192.168.16.1

    1ead618d3fce222bd87badcfde9e2211.png

    网络丢包是网络中常见的故障之一,它会引起网速降低甚至造成网络中断。发生网络故障在所难免,但是如何快速隔离和排除故障是网络管理人员应该具备的基本素质。

    一、网络数据包发送时通时断

    故障现象:

    通常故障发生时,该方向网络出现震荡性中断。使用Ping命令测试,发现在一段时间内数据包发送延时比正常值略高,间隔一小段时间数据包又全部丢失,丢包率超过50%,丢包曲线成规则状,网络服务基本不可用。

    故障分析:

    在局域网中引起网络发生振荡性时断时通,一般可能是由于互连的交换机中的某两个交换机间出现了环路,或者某个交换机的两个端口直接相连。

    这样就会造成局域网的生成树协议构建失败,不断重复检查并试图构建新的生成树网络,从而导致网络振荡性通断,同时伴随着交换机间不断重复地发送广播包,就会形成“广播风暴”,使交换机负担过重,网络传输通道严重被堵塞,无法正常的处理通信数据。

    环路虽然可能出现在某个接入交换机上,但会影响整个以三层交换机为核心的局域网的稳定运行。

    7a24c7c9d329e89fa5bc2630469ff09f.png

    故障处理:

    当发现网络数据包发送时通时断,丢包严重,特别是整个单位或整个楼层出现振荡性中断现象时,则可以判定应该是该单位的某个交换机上出现了环路所致。

    作为网络管理人员应首先查看各接入交换机的指示灯闪烁状态,通常出现环路状况会指示灯会急速闪烁,次数每秒4次以上,相连的交换机更为突出。

    逐个拨出交换机级联接入网线,同时实时监控交换机状态,在拨下某端口网线后,交换机指示灯恢复正常状态,再进一步查找,会发现该连接线的末端有线路形成环路,清理该网线后,网络恢复畅通。

    二、数据发送超时现象严重

    故障现象:

    ping的时候返回时间比较长,网络突然出现严重堵塞,打开网页速度缓慢,有时会因超时而中断。未发现网络设备有任何问题,该网络中有几台计算机速度明显变慢或者掉线,在禁用网卡或者中断网络后恢复正常。

    故障分析:

    首先,在一台用户终端上ping网关测试,结果可以ping通网关,但是数据包发送超时现象严重,丢包率30%左右,丢包不规律。

    其次,登陆用户交换机,运行arp -a命令,发现网关IP和网关MAC地址指向正确。

    通过上面的测试基本排除网络设置错误以及ARP欺骗,先看带宽,如果带宽充足,仍然有丢包的情况,这个问题可能是路由器/交换机/防火墙无法处理大流量,你已经达到了你硬件所能提供的最大的流量了。

    故障处理:

    这个一般是设备性能在该项目中没有选用正确,达到了上限了,主要是路由器、交换机在当下的网络中选用不合适,或者网线距离过长等问题,升级相应的设备,或减少项目中的接入量可以找到原因。

    三、数据包发现有严重延时

    故障现象:

    在一个大的网络中,大部分使用正常,只有一部分网络存在延时,使用Ping命令发现到某个方向网络时延特别大,甚至有少量丢包现象。

    故障分析:

    一般远程登陆到该方向的交换机,以华为系列交换机为例,输入下列命令:

    #Display cpu-usage 查看交换机CPU利用率

    1fd5b5e08b22cfd93a4950352e7e0b93.png

    #Display memory 查看内存利用率

    7e1ab51180ff4ad9b8576ae8a54fe2f0.png

    如果发现两者都非常高,再通过输入命令 #Display interface端口号,可以不断的检查各端口下的数据流。(ctrl+c终止)。

    fa4ed4ccc04c4676f0ed2d0a6ea0c366.png

    若发现其中的两个端口数据流量特别大,远高于正常使用的网络流量。对其数据流进行抓包分析,为避免影响整个网络的畅通,对所接入交换机进行处理。

    故障处理:

    进入该端口配置界面下,输入Shutdown命令,强制关闭该端口使其断网,联系该终端使用人员,令其终止下载进程后,再恢复其网络。

    968f339100d0926a259e0e0eb53788ea.png

    最新弱电资料更新—智能化施工定额与可视对讲施工报价12月5日

    展开全文
  • 所谓丢包,是指在网络数据收发过程中...接下来,我就以最常用反向代理服务器 Nginx 为例,带你一起看看,如何分析网络丢包 问题。 执行下面 hping3 命令,进一步验证 Nginx 是不是真可 以正常访问了。注意.

    所谓丢包,是指在网络数据的收发过程中,由于种种原因,数据包还没传输到应用程序中,就被丢弃了。这些被丢弃包的数量,除以总的传输包数,也就是我们常说的丢包率。丢包率是网络性能中最核心的指标之一。丢包通常会带来严重的性能下降,特别是对 TCP 来说,丢包通常意味着网络拥塞和重传,进而还会导致网络延迟增大、吞吐降低。

     

    一、 哪里可能丢包

    接下来,我就以最常用的反向代理服务器 Nginx 为例,带你一起看看如何分析网络丢包的问题。执行下面的 hping3 命令,进一步验证 Nginx 是不是可以正常访问。这里我没有使用 ping,是因为 ping 基于 ICMP 协议,而 Nginx 使用的是 TCP 协议。

    # -c表示发送10个请求,-S表示使用TCP SYN,-p指定端口为80
    hping3 -c 10 -S -p 80 192.168.0.30
    
    HPING 192.168.0.30 (eth0 192.168.0.30): S set, 40 headers + 0 data bytes
    len=44 ip=192.168.0.30 ttl=63 DF id=0 sport=80 flags=SA seq=3 win=5120 rtt=7.5 ms
    len=44 ip=192.168.0.30 ttl=63 DF id=0 sport=80 flags=SA seq=4 win=5120 rtt=7.4 ms
    len=44 ip=192.168.0.30 ttl=63 DF id=0 sport=80 flags=SA seq=5 win=5120 rtt=3.3 ms
    len=44 ip=192.168.0.30 ttl=63 DF id=0 sport=80 flags=SA seq=7 win=5120 rtt=3.0 ms
    len=44 ip=192.168.0.30 ttl=63 DF id=0 sport=80 flags=SA seq=6 win=5120 rtt=3027.2 ms
    
    --- 192.168.0.30 hping statistic ---
    10 packets transmitted, 5 packets received, 50% packet loss
    round-trip min/avg/max = 3.0/609.7/3027.2 ms

    从 hping3 的输出中,我们可以发现,发送了 10 个请求包,却只收到了 5 个回复,50%的包都丢了。再观察每个请求的 RTT 可以发现,RTT 也有非常大的波动变化,小的时候只有 3ms,而大的时候则有 3s。根据这些输出,我们基本能判断,已经发生了丢包现象。可以猜测,3s 的 RTT ,很可能是因为丢包后重传导致的。

    那到底是哪里发生了丢包呢?排查之前,我们可以回忆一下 Linux 的网络收发流程,先从理论上分析,哪里有可能会发
    生丢包。你不妨拿出手边的笔和纸,边回忆边在纸上梳理,思考清楚再继续下面的内容。在这里,为了帮你理解网络丢包的原理,我画了一张图,你可以保存并打印出来使用

    从图中你可以看出,可能发生丢包的位置,实际上贯穿了整个网络协议栈。换句话说,全程都有丢包的可能。

    • 在两台 VM 连接之间,可能会发生传输失败的错误,比如网络拥塞、线路错误等;
    • 在网卡收包后,环形缓冲区可能会因为溢出而丢包;
    • 在链路层,可能会因为网络帧校验失败、QoS 等而丢包;
    • 在 IP 层,可能会因为路由失败、组包大小超过 MTU 等而丢包;
    • 在传输层,可能会因为端口未监听、资源占用超过内核限制等而丢包;
    • 在套接字层,可能会因为套接字缓冲区溢出而丢包;
    • 在应用层,可能会因为应用程序异常而丢包;
    • 此外,如果配置了 iptables 规则,这些网络包也可能因为 iptables 过滤规则而丢包

    当然,上面这些问题,还有可能同时发生在通信的两台机器中。不过,由于我们没对 VM2做任何修改,并且 VM2 也只运行了一个最简单的 hping3 命令,这儿不妨假设它是没有问题的。为了简化整个排查过程,我们还可以进一步假设, VM1 的网络和内核配置也没问题。接下来,就可以从协议栈中,逐层排查丢包问题。
     

    二、 链路层

    当链路层由于缓冲区溢出等原因导致网卡丢包时,Linux 会在网卡收发数据的统计信息中记录下收发错误的次数。可以通过 ethtool 或者 netstat ,来查看网卡的丢包记录。

    netstat -i
    
    Kernel Interface table
    Iface      MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
    eth0       100       31      0      0 0             8      0      0      0 BMRU
    lo       65536        0      0      0 0             0      0      0      0 LRU

    RX-OK、RX-ERR、RX-DRP、RX-OVR ,分别表示接收时的总包数、总错误数、进入 Ring Buffer 后因其他原因(如内存不足)导致的丢包数以及 Ring Buffer 溢出导致的丢包数。

    TX-OK、TX-ERR、TX-DRP、TX-OVR 也代表类似的含义,只不过是指发送时对应的各个指标。

    这里我们没有发现任何错误,说明虚拟网卡没有丢包。不过要注意,如果用 tc 等工具配置了 QoS,那么 tc 规则导致的丢包,就不会包含在网卡的统计信息中。所以接下来,我们还要检查一下 eth0 上是否配置了 tc 规则,并查看有没有丢包。添加 -s 选项,以输出统计信息:

    tc -s qdisc show dev eth0
    
    qdisc netem 800d: root refcnt 2 limit 1000 loss 30%
     Sent 432 bytes 8 pkt (dropped 4, overlimits 0 requeues 0)
     backlog 0b 0p requeues 0

    可以看到, eth0 上配置了一个网络模拟排队规则(qdisc netem),并且配置了丢包率为 30%(loss 30%)。再看后面的统计信息,发送了 8 个包,但是丢了 4个。看来应该就是这里导致 Nginx 回复的响应包被 netem 模块给丢了。

    既然发现了问题,解决方法也很简单,直接删掉 netem 模块就可以了。执行下面的命令,删除 tc 中的 netem 模块:

    tc qdisc del dev eth0 root netem loss 30%

    删除后,重新执行之前的 hping3 命令,看看现在还有没有问题:

    hping3 -c 10 -S -p 80 192.168.0.30
    
    HPING 192.168.0.30 (eth0 192.168.0.30): S set, 40 headers + 0 data bytes
    len=44 ip=192.168.0.30 ttl=63 DF id=0 sport=80 flags=SA seq=0 win=5120 rtt=7.9 ms
    len=44 ip=192.168.0.30 ttl=63 DF id=0 sport=80 flags=SA seq=2 win=5120 rtt=1003.8 ms
    len=44 ip=192.168.0.30 ttl=63 DF id=0 sport=80 flags=SA seq=5 win=5120 rtt=7.6 ms
    len=44 ip=192.168.0.30 ttl=63 DF id=0 sport=80 flags=SA seq=6 win=5120 rtt=7.4 ms
    len=44 ip=192.168.0.30 ttl=63 DF id=0 sport=80 flags=SA seq=9 win=5120 rtt=3.0 ms
    
    --- 192.168.0.30 hping statistic ---
    10 packets transmitted, 5 packets received, 50% packet loss
    round-trip min/avg/max = 3.0/205.9/1003.8 ms

    不幸的是,从 hping3 的输出中可以看到还是 50% 的丢包,RTT 的波动也仍旧很大,从 3ms 到 1s。显然,问题还是没解决,丢包还在继续发生。不过,既然链路层已经排查完了,我们就继续向上层分析,看看网络层和传输层有没有问题。

     

    三、 网络层和传输层

    在网络层和传输层中,引发丢包的因素非常多。不过,其实想确认是否丢包,是非常简单的事,因为 Linux 已经为我们提供了各个协议的收发汇总情况。执行 netstat -s 命令,可以看到协议的收发汇总,以及错误信息:

    netstat -s
    #输出
    Ip:
        Forwarding: 1          //开启转发
        31 total packets received    //总收包数
        0 forwarded            //转发包数
        0 incoming packets discarded  //接收丢包数
        25 incoming packets delivered  //接收的数据包数
        15 requests sent out      //发出的数据包数
    Icmp:
        0 ICMP messages received    //收到的ICMP包数
        0 input ICMP message failed    //收到ICMP失败数
        ICMP input histogram:
        0 ICMP messages sent      //ICMP发送数
        0 ICMP messages failed      //ICMP失败数
        ICMP output histogram:
    Tcp:
        0 active connection openings  //主动连接数
        0 passive connection openings  //被动连接数
        11 failed connection attempts  //失败连接尝试数
        0 connection resets received  //接收的连接重置数
        0 connections established    //建立连接数
        25 segments received      //已接收报文数
        21 segments sent out      //已发送报文数
        4 segments retransmitted    //重传报文数
        0 bad segments received      //错误报文数
        0 resets sent          //发出的连接重置数
    Udp:
        0 packets received
        ...
    TcpExt:
        11 resets received for embryonic SYN_RECV sockets  //半连接重置数
        0 packet headers predicted
        TCPTimeouts: 7    //超时数
        TCPSynRetrans: 4  //SYN重传数
      ...

    netstat 汇总了 IP、ICMP、TCP、UDP 等各种协议的收发统计信息。不过,我们的目的是排查丢包问题,所以这里主要观察的是错误数、丢包数以及重传数。可以看到,只有 TCP 协议发生了丢包和重传,分别是:

    • 11 次连接失败重试(11 failed connection attempts)
    • 4 次重传(4 segments retransmitted)
    • 11 次半连接重置(11 resets received for embryonic SYN_RECV sockets)
    • 4 次 SYN 重传(TCPSynRetrans)
    • 7 次超时(TCPTimeouts)

    这个结果告诉我们,TCP 协议有多次超时和失败重试,并且主要错误是半连接重置。换句话说,主要的失败,都是三次握手失败。不过,虽然在这儿看到了这么多失败,但具体失败的根源还是无法确定。所以,我们还需要继续顺着协议栈来分析。接下来的几层又该如何分析呢?
     

    四、 iptables

    首先,除了网络层和传输层的各种协议,iptables 和内核的连接跟踪机制也可能会导致丢包。所以,这也是发生丢包问题时我们必须要排查的一个因素。

    先来看看连接跟踪,要确认是不是连接跟踪导致的问题,只需要对比当前的连接跟踪数和最大连接跟踪数即可。

    # 主机终端中查询内核配置
    $ sysctl net.netfilter.nf_conntrack_max
    net.netfilter.nf_conntrack_max = 262144
    $ sysctl net.netfilter.nf_conntrack_count
    net.netfilter.nf_conntrack_count = 182

    可以看到,连接跟踪数只有 182,而最大连接跟踪数则是 262144。显然,这里的丢包,不可能是连接跟踪导致的。

    接着,再来看 iptables。回顾一下 iptables 的原理,它基于 Netfilter 框架,通过一系列的规则,对网络数据包进行过滤(如防火墙)和修改(如 NAT)。这些 iptables 规则,统一管理在一系列的表中,包括 filter、nat、mangle(用于修改分组数据) 和 raw(用于原始数据包)等。而每张表又可以包括一系列的链,用于对 iptables 规则进行分组管理。

    对于丢包问题来说,最大的可能就是被 filter 表中的规则给丢弃了。要弄清楚这一点,就需要我们确认,那些目标为 DROP 和 REJECT 等会弃包的规则,有没有被执行到。可以直接查询 DROP 和 REJECT 等规则的统计信息,看看是否为0。如果不是 0 ,再把相关的规则拎出来进行分析。

    iptables -t filter -nvL
    #输出
    Chain INPUT (policy ACCEPT 25 packets, 1000 bytes)
     pkts bytes target     prot opt in     out     source               destination
        6   240 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            statistic mode random probability 0.29999999981
    
    Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination
    
    Chain OUTPUT (policy ACCEPT 15 packets, 660 bytes)
     pkts bytes target     prot opt in     out     source               destination
        6   264 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            statistic mode random probability 0.29999999981

    从 iptables 的输出中,你可以看到,两条 DROP 规则的统计数值不是 0,它们分别在INPUT 和 OUTPUT 链中。这两条规则实际上是一样的,指的是使用 statistic 模块,进行随机 30% 的丢包。0.0.0.0/0 表示匹配所有的源 IP 和目的 IP,也就是会对所有包都进行随机 30% 的丢包。看起来,这应该就是导致部分丢包的“罪魁祸首”了。

    执行下面的两条 iptables 命令,删除这两条 DROP 规则。

    
    root@nginx:/# iptables -t filter -D INPUT -m statistic --mode random --probability 0.30 -j DROP
    root@nginx:/# iptables -t filter -D OUTPUT -m statistic --mode random --probability 0.30 -j DROP

    再次执行刚才的 hping3 命令,看看现在是否正常

    hping3 -c 10 -S -p 80 192.168.0.30
    #输出
    HPING 192.168.0.30 (eth0 192.168.0.30): S set, 40 headers + 0 data bytes
    len=44 ip=192.168.0.30 ttl=63 DF id=0 sport=80 flags=SA seq=0 win=5120 rtt=11.9 ms
    len=44 ip=192.168.0.30 ttl=63 DF id=0 sport=80 flags=SA seq=1 win=5120 rtt=7.8 ms
    ...
    len=44 ip=192.168.0.30 ttl=63 DF id=0 sport=80 flags=SA seq=9 win=5120 rtt=15.0 ms
    
    --- 192.168.0.30 hping statistic ---
    10 packets transmitted, 10 packets received, 0% packet loss
    round-trip min/avg/max = 3.3/7.9/15.0 ms

    这次输出你可以看到,现在已经没有丢包了,并且延迟的波动变化也很小。看来,丢包问题应该已经解决了。

    不过,到目前为止,我们一直使用的 hping3 工具,只能验证案例 Nginx 的 80 端口处于正常监听状态,却还没有访问 Nginx 的 HTTP 服务。所以,不要匆忙下结论结束这次优化,我们还需要进一步确认,Nginx 能不能正常响应 HTTP 请求。我们继续在终端二中,执行如下的 curl 命令,检查 Nginx 对 HTTP 请求的响应:

    $ curl --max-time 3 http://192.168.0.30
    curl: (28) Operation timed out after 3000 milliseconds with 0 bytes received

    奇怪,hping3 的结果显示Nginx 的 80 端口是正常状态,为什么还是不能正常响应 HTTP 请求呢?别忘了,我们还有个大杀器——抓包操作。看来有必要抓包看看了。

     

    五、 tcpdump

    执行下面的 tcpdump 命令,抓取 80 端口的包

    tcpdump -i eth0 -nn port 80
    #输出
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes

    然后,切换到终端二中,再次执行前面的 curl 命令:

    curl --max-time 3 http://192.168.0.30
    curl: (28) Operation timed out after 3000 milliseconds with 0 bytes received

    等到 curl 命令结束后,再次切换回终端一,查看 tcpdump 的输出:

    14:40:00.589235 IP 10.255.255.5.39058 > 172.17.0.2.80: Flags [S], seq 332257715, win 29200, options [mss 1418,sackOK,TS val 486800541 ecr 0,nop,wscale 7], length 0
    14:40:00.589277 IP 172.17.0.2.80 > 10.255.255.5.39058: Flags [S.], seq 1630206251, ack 332257716, win 4880, options [mss 256,sackOK,TS val 2509376001 ecr 486800541,nop,wscale 7], length 0
    14:40:00.589894 IP 10.255.255.5.39058 > 172.17.0.2.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 486800541 ecr 2509376001], length 0
    14:40:03.589352 IP 10.255.255.5.39058 > 172.17.0.2.80: Flags [F.], seq 76, ack 1, win 229, options [nop,nop,TS val 486803541 ecr 2509376001], length 0
    14:40:03.589417 IP 172.17.0.2.80 > 10.255.255.5.39058: Flags [.], ack 1, win 40, options [nop,nop,TS val 2509379001 ecr 486800541,nop,nop,sack 1 {76:77}], length 0

    从 tcpdump 的输出中,我们就可以看到:

    • 前三个包是正常的 TCP 三次握手,这没问题;
    • 但第四个包却是在 3 秒以后了,并且还是客户端(VM2)发送过来的 FIN 包,说明客户端的连接关闭了

    根据 curl 设置的 3 秒超时选项,你应该能猜到,这是因为 curl 命令超时后退出了。用 Wireshark 的 Flow Graph 来表示,
    你可以更清楚地看到上面这个问题:

    这里比较奇怪的是,我们并没有抓取到 curl 发来的 HTTP GET 请求。那究竟是网卡丢包了,还是客户端就没发过来呢?

    可以重新执行 netstat -i 命令,确认一下网卡有没有丢包问题:

    netstat -i
    
    Kernel Interface table
    Iface      MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
    eth0       100      157      0    344 0            94      0      0      0 BMRU
    lo       65536        0      0      0 0             0      0      0      0 LRU

    从 netstat 的输出中,你可以看到,接收丢包数(RX-DRP)是 344,果然是在网卡接收时丢包了。不过问题也来了,为什么刚才用 hping3 时不丢包,现在换成 GET 就收不到了呢?还是那句话,遇到搞不懂的现象,不妨先去查查工具和方法的原理。我们可以对比一下这两个工具:

    • hping3 实际上只发送了 SYN 包;
    • curl 在发送 SYN 包后,还会发送 HTTP GET 请求。HTTP GET本质上也是一个 TCP 包,但跟 SYN 包相比,它还携带了 HTTP GET 的数据。

    通过这个对比,你应该想到了,这可能是 MTU 配置错误导致的。为什么呢?

    其实,仔细观察上面 netstat 的输出界面,第二列正是每个网卡的 MTU 值。eth0 的 MTU只有 100,而以太网的 MTU 默认值是 1500,这个 100 就显得太小了。当然,MTU 问题是很好解决的,把它改成 1500 就可以了。

    ifconfig eth0 mtu 1500

    修改完成后,再切换到终端二中,再次执行 curl 命令,确认问题是否真的解决了:

    curl --max-time 3 http://192.168.0.30/
    #输出
    <!DOCTYPE html>
    <html>
    ...
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>

    非常不容易呀,这次终于看到了熟悉的 Nginx 响应,说明丢包的问题终于彻底解决了。

    展开全文
  • 原创文章,转载请注明: 转载自系统技术非业余研究 本文链接地址: dropwatch 网络协议栈丢包检查利器 ...通常这个工具能解决大部分的问题,但是比如说wireshark发现丢包,那深层次的原因就很难解释了。这


    http://blog.yufeng.info/archives/2497 

    原创文章,转载请注明: 转载自系统技术非业余研究

    本文链接地址: dropwatch 网络协议栈丢包检查利器

    在做网络服务器的时候,会碰到各种各样的网络问题比如说网络超时,通常一般的开发人员对于这种问题最常用的工具当然是tcpdump或者更先进的wireshark来进行抓包分析。通常这个工具能解决大部分的问题,但是比如说wireshark发现丢包,那深层次的原因就很难解释了。这不怪开发人员,要怪就怪linux网络协议栈太深。我们来看下:
    network-stack

    这7层里面每个层都可能由于各种各样的原因,比如说缓冲区满,包非法等,把包丢掉,这样的问题就需要特殊的工具来发现了。 好了,主角dropwatch出场.
    它的官方网站在这里

    What is Dropwatch

    Dropwatch is a project I am tinkering with to improve the visibility developers and sysadmins have into the Linux networking stack. Specifically I am aiming to improve our ability to detect and understand packets that get dropped within the stack.

    Dropwatch定位很清晰,就是用来查看协议栈丢包的问题。

    RHEL系的系统安装相当简单,yum安装下就好:

    $ uname -r
    2.6.32-131.21.1.tb477.el6.x86_64
    $ sudo yum install dropwatch

    man dropwatch下就可以得到使用的帮助,dropwatch支持交互模式, 方便随时启动和停止观测。

    使用也是很简单:

    sudo dropwatch -l kas
    Initalizing kallsymsa db
    dropwatch> start
    Enabling monitoring...
    Kernel monitoring activated.
    Issue Ctrl-C to stop monitoring
    1 drops at netlink_unicast+251
    15 drops at unix_stream_recvmsg+32a
    3 drops at unix_stream_connect+1dc

    -l kas的意思是获取drop点的符号信息,这样的话针对源码就可以分析出来丢包的地方。

    同学们可以参考这篇文章(Using netstat and dropwatch to observe packet loss on Linux servers):http://prefetch.net/blog/index.php/2011/07/11/using-netstat-and-dropwatch-to-observe-packet-loss-on-linux-servers/

    那他的原理是什么呢?在解释原理之前,我们先看下这个工具的对等的stap脚本:

    cat /usr/share/doc/systemtap-1.6/examples/network/dropwatch.stp
    #!/usr/bin/stap
     
    ############################################################
    # Dropwatch.stp
    # Author: Neil Horman <nhorman@redhat.com>
    # An example script to mimic the behavior of the dropwatch utility
    ############################################################
     
    # Array to hold the list of drop points we find
    global locations
     
    # Note when we turn the monitor on and off
    probe begin { printf("Monitoring for dropped packets\n") }
    probe end { printf("Stopping dropped packet monitor\n") }
     
    # increment a drop counter for every location we drop at
    probe kernel.trace("kfree_skb") { locations[$location] <<< 1 }
     
    # Every 1 seconds report our drop locations
    probe timer.sec(1)
    {
      printf("\n")
      foreach (l in locations-) {
        printf("%d packets dropped at %s\n",
               @count(locations[l]), symname(l))
      }
      delete locations
    }

    这个脚本核心的地方就在于这行:
    probe kernel.trace(“kfree_skb”) { locations[$location] <<< 1 }
    当kfree_skb被调用的时候,内核就记录下这个drop协议栈的位置,同时透过netlink通知dropwatch用户态的部分收集这个位置,同时把它整理显示出来.以上就是dropwatch的工作流程。

    现在的问题是内核什么地方,什么时候会调用kfree_skb这个函数呢? 我们继续追查下:
    dropwatch需要对内核打patch,当然RHEL5U4以上的内核都已经打了patch。
    patch在这里下载:https://fedorahosted.org/releases/d/r/dropwatch/dropwatch_kernel_patches.tbz2
    通过查看里面的5个patch,我们知道drop主要修改了以下几个文件:

    include/linux/netlink.h
    include/trace/skb.h
    net/core/Makefile
    net/core/net-traces.c
    include/linux/skbuff.h
    net/core/datagram.c
    include/linux/net_dropmon.h
    net/core/drop_monitor.c
    include/linux/Kbuild
    net/Kconfig
    net/core/Makefile

    我们透过RHEL5U4的代码可以清楚的看到:

    //include/linux/skbuff.h
    extern void kfree_skb(struct sk_buff *skb);
    extern void consume_skb(struct sk_buff *skb);

    这些patch的作用是使得支持dropwatch的内核把kfree_skb分成二类: 1. 人畜无害的调用consume_skb 2. 需要丢包的调用kfree_skb 同时提供基础的netlink通信往用户空间传递位置信息。

    知道了这点,我们在RHEL 5U4的源码目录下: linux-2.6.18.x86_64/net/ipv4 或者 linux-2.6.18.x86_64/net/core下 grep下

    grep -rin kfree_skb  .
    ./tcp_input.c:3122:                     __kfree_skb(skb);
    ./tcp_input.c:3219:                     __kfree_skb(skb);
    ./tcp_input.c:3234:             __kfree_skb(skb);
    ./tcp_input.c:3318:                             __kfree_skb(skb);
    ...
    ./ip_fragment.c:166:static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work)
    ./ip_fragment.c:171:    kfree_skb(skb);
    ./ip_fragment.c:211:            frag_kfree_skb(fp, work);
    ./ip_fragment.c:452:            frag_kfree_skb(fp, NULL);
    ./ip_fragment.c:578:                    frag_kfree_skb(free_it, NULL);
    ./ip_fragment.c:607:    kfree_skb(skb);
    ./ip_fragment.c:732:    kfree_skb(skb);
    ./udp.c:1028:   kfree_skb(skb);
    ./udp.c:1049:           kfree_skb(skb);
    ./udp.c:1069:                   kfree_skb(skb);
    ./udp.c:1083:                   kfree_skb(skb);
    ./udp.c:1134:                                   kfree_skb(skb1);
    ./udp.c:1229:   kfree_skb(skb);
    ./udp.c:1242:   kfree_skb(skb);
    ./udp.c:1258:   kfree_skb(skb);
    ./udp.c:1418:                           kfree_skb(skb);
    ./ip_sockglue.c:286:            kfree_skb(skb);
    ./ip_sockglue.c:322:            kfree_skb(skb);
    ./ip_sockglue.c:398:    kfree_skb(skb);
    ./devinet.c:1140:               kfree_skb(skb);
    ./xfrm4_ninput.c:29:    kfree_skb(skb);
    ./xfrm4_ninput.c:122:   kfree_skb(skb);
    ./tunnel4.c:85: kfree_skb(skb);
    ./icmp.c:47: *                                  and moved all kfree_skb() up to
    ./icmp.c:1046:  kfree_skb(skb);
    ./ip_forward.c:121:     kfree_skb(skb);
    ./netfilter.c:73:               kfree_skb(*pskb);
    ./netfilter.c:114:              kfree_skb(*pskb);
    ./netfilter/ip_queue.c:277:             kfree_skb(skb);
    ./netfilter/ip_queue.c:335:     kfree_skb(nskb);
    ./netfilter/ip_queue.c:373:                     kfree_skb(e->skb);
    ./netfilter/ip_queue.c:556:             kfree_skb(skb);
    ...
    ./netfilter/ipt_TCPMSS.c:153:           kfree_skb(*pskb);
    ./netfilter/ipt_ULOG.c:435:                     kfree_skb(ub->skb);
    ./tcp.c:1458:                           kfree_skb(skb);
    ./tcp.c:1577:           __kfree_skb(skb);
    ./ip_gre.c:482:         kfree_skb(skb2);
    ./ip_gre.c:497:                 kfree_skb(skb2);
    ./ip_gre.c:504:                 kfree_skb(skb2);
    ...
    ./ip_gre.c:892: dev_kfree_skb(skb);
    ./raw.c:244:            kfree_skb(skb);
    ./raw.c:254:            kfree_skb(skb);
    ./raw.c:329:    kfree_skb(skb);
    ./tcp_ipv4.c:1039:      kfree_skb(skb);
    ./tcp_ipv4.c:1151:      kfree_skb(skb);
    ./ipvs/ip_vs_xmit.c:213:        kfree_skb(skb);
    ./ipvs/ip_vs_xmit.c:290:        kfree_skb(skb);
    ./ipvs/ip_vs_xmit.c:374:                        kfree_skb(skb);
    ./ipvs/ip_vs_xmit.c:378:                kfree_skb(skb);
    ./ipvs/ip_vs_xmit.c:423:        kfree_skb(skb);
    ./ipvs/ip_vs_xmit.c:480:        kfree_skb(skb);
    ./ipvs/ip_vs_xmit.c:553:        dev_kfree_skb(skb);
    ./ipvs/ip_vs_core.c:197:        kfree_skb(*pskb);
    ./ipvs/ip_vs_core.c:829:        kfree_skb(*pskb);
    ./ipconfig.c:504:       kfree_skb(skb);
    ./ipconfig.c:1019:      kfree_skb(skb);
    ./xfrm4_input.c:50:     kfree_skb(skb);
    ./xfrm4_input.c:162:    kfree_skb(skb);
    ./fib_semantics.c:292:          kfree_skb(skb);
    ./ipip.c:414:           kfree_skb(skb2);
    ./ipip.c:429:                   kfree_skb(skb2);
    ./ipip.c:436:                   kfree_skb(skb2);
    ./ipip.c:444:                   kfree_skb(skb2);
    ./ipip.c:458:   kfree_skb(skb2);
    ./ipip.c:482:                   kfree_skb(skb);
    ./ipip.c:609:                   dev_kfree_skb(skb);
    ./ipip.c:615:           dev_kfree_skb(skb);
    ./ipip.c:654:   dev_kfree_skb(skb);
    ./ipmr.c:185:   kfree_skb(skb);
    ...
    ./ip_output.c:763:      kfree_skb(skb);
    ./ip_output.c:964:                              kfree_skb(skb);
    ./ip_output.c:1313:             kfree_skb(skb);

    我们可以看到一堆可以丢包的点。
    当我们观察到dropwatch发现丢包的时候,可以根据符号信息结合以上的源码轻松的分析出来问题所在。

    小结: 工具是知识的积累。

    祝玩得开心!

    Post Footer automatically generated by wp-posturl plugin for wordpress.


    展开全文
  • 一、消息收发流程图及丢包可能原因 1.在网卡收包后,环形缓冲区可能会因为溢出而丢包; 2.在链路层,可能会因为网络帧校验失败、QoS 等而丢包; 3.在 IP 层,可能会因为路由失败、组包大小超过 MTU 等而丢包; ...

    一、消息收发流程图及丢包可能原因

    1. 在网卡收包后,环形缓冲区可能会因为溢出而丢包;

    2. 在链路层,可能会因为网络帧校验失败、QoS 等而丢包;

    3. 在 IP 层,可能会因为路由失败、组包大小超过 MTU 等而丢包;

    4. 在传输层,可能会因为端口未监听、资源占用超过内核限制等而丢包;

    5. 在套接字层,可能会因为套接字缓冲区溢出而丢包;

    6. 在应用层,可能会因为应用程序异常而丢包;

    7. 如果配置了 iptables 规则,这些网络包也可能因为 iptables 过滤规则而丢包。

     

    二、逐层排查丢包问题

     

    使用hping3检查丢包情况:

    发现问题:  50% 的丢包;RTT 的波动也仍旧很大,从 3ms 到 1s。

    1. 链路层

    1.1 检查虚拟网卡

    执行netstat -i

    RX-OK:接收时总包数

    RX-ERR:总错误数

    RX-DRP:进入 Ring Buffer 后因其他原因(如内存不足)导致的丢包数

    RX-OVR:Ring Buffer 溢出导致的丢包数

    从这个输出中,没发现任何错误,说明虚拟网卡没有丢包。

    1.2 检查TC规则

    检查 eth0 上是否配置了 tc 规则

    发现问题:eth0 上面配置了一个网络模拟排队规则,并且配置了丢包率为 30%

    处理方法:删除 tc 中的 netem 模块

    2. 网络层和传输层

    执行 netstat -s

    发现有5个问题,如上。

    这个结果说明,TCP 协议有多次超时和失败重试,并且主要错误是半连接重置。

    即:,主要的失败,是三次握手失败。

    3. iptables 和内核的连接跟踪机制

    3.1 内核的连接跟踪机制

    连接跟踪数只有 182,而最大连接跟踪数则是 262144,并没有问题。

    3.2 查看iptables规则

    发现问题:两条 DROP 规则,使用 statistic 模块,进行随机 30% 的丢包

    处理办法:把这两条规则直接删除

    重新执行刚才的 hping3 命令,看看现在是否正常:

    现在已经没有丢包了。

    hping3 工具,只能验证 Nginx 的 80 端处于正常监听状态, 还没有访问 Nginx 的 HTTP 服务

    执行curl 命令,检查 Nginx 对 HTTP请求的响应:

    可以发现,这次连接超时了。

    4. tcpdump

    4.1  tcpdump检查丢包环节在哪里

    服务端执行tcpdump 命令,抓取 80 端口的包

    客户端执行curl命令

    查看 tcpdump 的输出

    前三个包是正常的 TCP 三次握手,没问题。(SYN,SYN ACK,ACK)

    四个包却是在 3 秒才收到,并且还是客户端发送过来的 FIN 包。

    也就说明,客户端的连接关闭了。

    4.2 重新执行 netstat -i 令,检查网卡有没有丢包

    果然是在网卡接收时丢包了。

    hping3 时不丢包,换成 GET 就收不到

    4.3 检查最大传输单元MTU

    发现问题: eth0 的 MTU 只有 100,而以太网的 MTU 默认值是 1500。

    解决办法:MTU改成 1500

    4.4. 再次执行 curl 命令

    问题解决

    展开全文
  • dropwatch 网络协议栈丢包检查利器

    千次阅读 2013-04-25 23:49:54
    通常这个工具能解决大部分的问题,但是比如说wireshark发现丢包,那深层次的原因就很难解释了。这不怪开发人员,要怪就怪linux网络协议栈太深。我们来看下: 这7层里面每个层都可能由于各种各样的原因,比如说...
  • linux网络编程

    2017-07-01 16:08:08
    1.UDP 简称:用户数据报协议 原理:数据报协议特点用一句话来形容就是他不够安全,他不关心数据是否被... 成的丢包,数据排序等数据发送变化等结果,而且不同于TCP一点是每次UDP 传输数据时候会将数据
  • 一般使用它进行实时性数据的传输,主要是因为它快,但因为它是不可靠的一种传输协议,所以不可避免的会出现丢包现象。本文就具体讨论导致UDP传输数据包丢失的原因以及一些基本的规避方法: 路由器转发造成的数据包...
  • 仔细思考后找到了原因,nload统计是平均速率,但是网络传输是很快,并不是一个稳定速率,可能某一瞬时速率超过了前兆网卡极限,就发上了丢包现象。所以平均速率并不能很好地说明问题,尽管平均速率很低,...
  • 1. LVS故障: 近日因公司大促, mysql从服务器前端共享一台LVS因流量跑到2Gps 而出现 LVS丢包, Client端代码不停抛出mysql connect failed异常.   故障特征:大流量时为LVSCPU其中一个core使用率100%, 其他...
  • TCP/IP协议是一种流协议,...产生粘包问题的原因 1.SQ_SNDBUF套接字本身有缓冲区(发送缓冲区,接收缓冲区) 2.tcp传送的网络数据最大值MSS大小限制 3.链路层也有MTU(最大传输单元)大小限制,如果数据包大于>...
  • 客户在linux centOS上搭建我们公司一个项目,web服务器使用是tomcat,我们系统是c/s架构一个系统,在客户端打开,点击登录时候,直接弹出“404bad request”。 我在客户现场后,远程调试启动...
  • linux-socket编程(四)

    2020-05-06 23:59:18
    TCP:基于字节流传输服务,无边界(包与包之间没有边界),所以容易产生粘包,但是不会丢包。 粘包含义:由于TCP在传输数据时候是无边界,所以数据对tcp来说就是一堆没有结构区别字节块,因此就会导致如下...
  • 线上服务运行缓慢故障排查思路与解决(Linux服务器) 一.分析思路 1.排除本机自身原因 2.服务器性能分析、网络分析 ...注:可以使用在线测试服务器延迟和丢包的工具 Ping.pe 使用iperf命令测试服务器带宽,它分为
  • Linux系统运维常见面试简答题系列(二)(14题)如内容有不正之处,烦请给予...此报错为iptables报错信息,连接跟踪表已满,开始丢包,可能的原因是由于频繁的连接、关闭,或者网络的一些TCP的连接导致的解决方法:1...
  • 此报错为iptables报错信息,连接跟踪表已满,开始丢包,可能的原因是由于频繁的连接、关闭,或者网络的一些TCP的连接导致的 解决方法: 1、加大跟踪表的大小  2、禁用一些不必跟踪的连接状态  3、禁用模块 ip_vs ...
  • 基本思想:RTO有两种原因,一是网络上确实发生了丢包,二是由于IP层转发路径延迟不同造成RTO。对于后者,称之为F-RTO,RTO发生之前ACK应该发生在RTO发生之后到达发送端。如果一直收不到ACK,证明确实是发生了...
  • ICMP协议

    2019-06-30 13:02:54
    参考链接:https://www.cnblogs.com/embedded-linux/p/7068130.html...如果丢包了,IP协议并不能通知传输层是否丢包以及丢包的原因。所以我们就需要一种协议来完成这样的功能–ICMP协议。 ICMP协议的功能主要有: ...
  • 随承载用户数量的增加...设备之间通过VCS组成冷备,但即使有双机软件保护,宕机、网络丢包等问题发生时业务仍会受影响。这样的系统架构下为保证SLA,有时候需要深入Linux系统内核或硬件层面分析机器重启的原因。 接...
  • 六月 一周小结知识点小结hostnameLinux文件大小F5健康检查策略关于网络堵塞Linux重启后,resolve.conf压测出现丢包 知识点小结 hostname hostname意义:通过hostname 查找IP 在生产遇到这样一个问题。交易到zk...
  • 在数据中心网络内,机器之间数据传输往返时间(rtt)一般在10ms以内,为此调内部服务超时时间一般会设置成50ms、200ms、500ms等,如果在传输过程中出现丢包,这样服务超时时间,tcp层有机会发现并重传一次数据么...
  • 在这里仅列举两个最主要的原因,一方面,随着近年来企业信息化进程的深入,企业里各种系统的数据量持续上升,这一切给数据的管理、维护和安全带来了机会和挑战,另一方面,企业间同质化竞争的加剧,也迫使企业加强...
  • 手机 pdf 阅读器

    2009-02-12 23:00:29
    搜索功能由于服务器端的原因,目前仅完成了浏览器部分,稍后会支持下载,HTML解析部分目前存在一点小BUG,格式偶尔会有问题 [2008.5.31] Ver:3.2.19 无功能上的更新,仅修正了3.2.18的bug [2008.5.22] Ver:3.2.18...
  • 04-主从同步应用场景及切换从库不数据多方案介绍.avi 05-mysql数据库读写分离介绍及企业生产实现方案.avi 06-根据企业业务拆分业务应用到不同从库思想.avi 07-mysql主从复制原理画图深入浅出讲解.avi 08-mysql...

空空如也

空空如也

1 2
收藏数 28
精华内容 11
关键字:

linux网络丢包的原因

linux 订阅