精华内容
下载资源
问答
  • 网络丢包故障定位全景指南

    千次阅读 2021-03-05 10:32:23
    作者简介:冯荣,腾讯云网络高级工程师,腾讯云网络核心开发人员。 万字长文建议收藏 引言本期分享一个比较常见的⽹络问题--丢包。例如...

    作者简介:冯荣,腾讯云网络高级工程师,腾讯云网络核心开发人员    

    万字长文  建议收藏                         

    引言

    本期分享一个比较常见的⽹络问题--丢包。例如我们去ping⼀个⽹站,如果能ping通,且⽹站返回信息全⾯,则说明与⽹站服务器的通信是畅通的,如果ping不通,或者⽹站返回的信息不全等,则很可能是数据被丢包了,类似情况想必⼤家都不陌⽣。针对⽹络丢包,本⽂提供⼀些常见的丢包故障定位⽅法,希望能够帮助⼤家对⽹络丢包有更多的认识,遇到丢包莫要慌,且跟着⼀起来涨姿(知)势(识)···

    什么是丢包

    数据在Internet上是以数据包为单位传输的,单位为字节,数据在⽹络上传输,受⽹络设备,⽹络质量等原因的影响,使得接收到的数据⼩于发送出去的数据,造成丢包。

    数据包接收、发送原理

    发送数据包:


    1.应⽤程序的数据包,在TCP层增加TCP报⽂头,形成可传输的数据包。
    2.在IP层增加IP报头,形成IP报⽂。
    3.经过数据⽹卡驱动程序将IP包再添加14字节的MAC头,构成frame(暂⽆CRC),frame(暂⽆CRC)中含有发送端和接收端的MAC地址。
    4.驱动程序将frame(暂⽆CRC)拷贝到⽹卡的缓冲区,由⽹卡处理。
    5.⽹卡为frame(暂⽆CRC)添加头部同步信息和CRC校验,将其封装为可以发送的packet,然后再发送到⽹线上,这样说就完成了⼀个IP报⽂的发送了,所有连接到这个⽹线上的⽹卡都可以看到该packet

    接收数据包:

    1.⽹卡收到⽹线上的packet,⾸先检查packet的CRC校验,保证完整性,然后将packet头去掉,得到frame。(⽹卡会检查MAC包内的⽬的MAC地址是否和本⽹卡的MAC地址⼀样,不⼀样则会丢弃。)
    2.⽹卡将frame拷贝到预分配的ring buffer缓冲。
    3.⽹卡驱动程序通知内核处理,经过TCP/IP协议栈层层解码处理。
    4.应⽤程序从socket buffer 中读取数据。

    核心思路

    了解了收发包的原理,可以了解到丢包原因主要会涉及⽹卡设备、⽹卡驱动、内核协议栈三⼤类。以下我们将遵循“从下到上分层分析(各层可能性出现的丢包场景),然后查看关键信息,最终得出分析结果”的原则展开介绍。

      目录--网络丢包情形概览

    > 硬件网卡丢包

    > 网卡驱动丢包

    > 以太网链路层丢包

    > 网络IP层丢包

    > 传输层UDP/TCP丢包

    > 应用层socket丢包

    针对以上6种情形,分别作出如下详述~

    硬件网

    Ring Buffer溢出 

    如图所示,物理介质上的数据帧到达后首先由NIC(网络适配器)读取,写入设备内部缓冲区Ring Buffer中,再由中断处理程序触发Softirq从中消费,Ring Buffer的大小因网卡设备而异。当网络数据包到达(生产)的速率快于内核处理(消费)的速率时,Ring Buffer很快会被填满,新来的数据包将被丢弃;

    查看:

    通过ethtool或/proc/net/dev可以查看因Ring Buffer满而丢弃的包统计,在统计项中以fifo标识:

    $ ethtool -S eth0|grep rx_fifo
    rx_fifo_errors: 0
    $ cat /proc/net/dev
    Inter-|Receive | Transmitface |bytes packets errs drop fifo frame compressed 
    multicast|bytes packets errs drop fifo colls carrier compressed
    eth0: 17253386680731 42839525880 0 0 0 0 0 244182022 14879545018057 41657801805 0 0 0 0 0 0
    

    # 查看eth0网卡Ring Buffer最大值和当前设置

    $ ethtool -g eth0
    

    解决方案:修改网卡eth0接收与发送硬件缓存区大小

    $ ethtool -G eth0 rx 4096 tx 4096
    

    网卡端口协商丢包

    1. 查看网卡丢包统计:ethtool -S eth1/eth0

    2. 查看网卡配置状态:ethtool eth1/eth0

    主要查看网卡和上游网络设备协商速率和模式是否符合预期;

    解决方案:

    1  重新自协商:  ethtool -r  eth1/eth0;

    2  如果上游不支持自协商,可以强制设置端口速率:

    ethtool -s eth1 speed 1000 duplex full autoneg off
    

    网卡流控丢包

    1. 查看流控统计:

    ethtool -S eth1 | grep control
    

    rx_flow_control_xon是在网卡的RX Buffer满或其他网卡内部的资源受限时,给交换机端口发送的开启流控的pause帧计数。对应的,tx_flow_control_xoff是在资源可用之后发送的关闭流控的pause帧计数。

    2 .查看网络流控配置:ethtool -a eth1

    解决方案:关闭网卡流控

    ethtool -A ethx autoneg off //自协商关闭
    ethtool -A ethx tx off //发送模块关闭
    ethtool -A ethx rx off //接收模块关闭
    

    报文mac地址丢包

    一般计算机网卡都工作在非混杂模式下,此时网卡只接受来自网络端口的目的地址指向自己的数据,如果报文的目的mac地址不是对端的接口的mac地址,一般都会丢包,一般这种情况很有可能是源端设置静态arp表项或者动态学习的arp表项没有及时更新,但目的端mac地址已发生变化(换了网卡),没有更新通知到源端(比如更新报文被丢失,中间交换机异常等情况);

    查看: 

    1.目的端抓包,tcpdump可以开启混杂模式,可以抓到对应的报文,然后查看mac地址;

    2.源端查看arp表或者抓包(上一跳设备),看发送的mac地址是否和下一跳目的端的mac地址一致;

    解决方案:

    1.刷新arp表然后发包触发arp重新学习(可能影响其他报文,增加延时,需要小心操作);

    2.可以在源端手动设置正确的静态的arp表项;

    其他网卡异常丢包

    这类异常比少见,但如果都不是上面哪些情况,但网卡统计里面任然有丢包计数,可以试着排查一下:

    网卡firmware版本:

    排查一下网卡phy芯片firmware是不是有bug,安装的版本是不是符合预期,查看 ethtool -i eth1:

    和厂家提case询问是不是已知问题,有没有新版本等;

    网线接触不良:

    如果网卡统计里面存在crc error 计数增长,很可能是网线接触不良,可以通知网管排查一下:

    ethtool -S eth0
    

    解决方案:一般试着重新插拔一下网线,或者换一根网线,排查插口是否符合端口规格等;

    报文长度丢包

    网卡有接收正确报文长度范围,一般正常以太网报文长度范围:64-1518,发送端正常情况会填充或者分片来适配,偶尔会发生一些异常情况导致发送报文不正常丢包;


    查看:

    ethtool -S eth1|grep length_errors
    

    解决方案:

    1  调整接口MTU配置,是否开启支持以太网巨帧;

    2  发送端开启PATH MTU进行合理分片;

    简单总结一下网卡丢包:

    网卡驱动丢包

    查看:ifconfig eth1/eth0 等接口

    1.RX errors: 表示总的收包的错误数量,还包括too-long-frames错误,Ring Buffer 溢出错误,crc 校验错误,帧同步错误,fifo overruns 以及 missed pkg 等等。

    2.RX dropped: 表示数据包已经进入了 Ring Buffer,但是由于内存不够等系统原因,导致在拷贝到内存的过程中被丢弃。

    3.RX overruns: 表示了 fifo 的 overruns,这是由于 Ring Buffer(aka Driver Queue) 传输的 IO 大于 kernel 能够处理的 IO 导致的,而 Ring Buffer 则是指在发起 IRQ 请求之前的那块 buffer。很明显,overruns 的增大意味着数据包没到 Ring Buffer 就被网卡物理层给丢弃了,而 CPU 无法即使的处理中断是造成 Ring Buffer 满的原因之一,上面那台有问题的机器就是因为 interruprs 分布的不均匀(都压在 core0),没有做 affinity 而造成的丢包。

    4. RX frame: 表示 misaligned 的 frames。

    5. 对于 TX 的来说,出现上述 counter 增大的原因主要包括 aborted transmission, errors due to carrirer, fifo error, heartbeat erros 以及 windown error,而 collisions 则表示由于 CSMA/CD 造成的传输中断。

    驱动溢出丢包

    netdev_max_backlog是内核从NIC收到包后,交由协议栈(如IP、TCP)处理之前的缓冲队列。每个CPU核都有一个backlog队列,与Ring Buffer同理,当接收包的速率大于内核协议栈处理的速率时,CPU的backlog队列不断增长,当达到设定的netdev_max_backlog值时,数据包将被丢弃。

    查看:

    通过查看/proc/net/softnet_stat可以确定是否发生了netdev backlog队列溢出:

    其中:每一行代表每个CPU核的状态统计,从CPU0依次往下;每一列代表一个CPU核的各项统计:第一列代表中断处理程序收到的包总数;第二列即代表由于netdev_max_backlog队列溢出而被丢弃的包总数。从上面的输出可以看出,这台服务器统计中,并没有因为netdev_max_backlog导致的丢包。

    解决方案:

    netdev_max_backlog的默认值是1000,在高速链路上,可能会出现上述第二统计不为0的情况,可以通过修改内核参数net.core.netdev_max_backlog来解决:

    $ sysctl -w net.core.netdev_max_backlog=2000
    

    单核负载高导致丢包

    单核CPU软中断占有高, 导致应用没有机会收发或者收包比较慢,即使调整netdev_max_backlog队列大小仍然会一段时间后丢包,处理速度跟不上网卡接收的速度;

    查看:mpstat -P ALL 1

    单核软中断占有100%,导致应用没有机会收发或者收包比较慢而丢包;

    解决方案

    1.调整网卡RSS队列配置:

    查看:ethtool -x ethx;

    调整:ethtool -X ethx xxxx;

    2.看一下网卡中断配置是否均衡 cat /proc/interrupts

    调整:

    1) irqbalance 调整;
    # 查看当前运行情况
    service irqbalance status
    # 终止服务
    service irqbalance stop
    2) 中断绑CPU核 echo mask > /proc/irq/xxx/smp_affinity
    

    3.根据CPU和网卡队列个数调整网卡多队列和RPS配置

    -CPU大于网卡队列个数:

    查看网卡队列 ethtool -x ethx;

    协议栈开启RPS并设置RPS;

    echo $mask(CPU配置)> /sys/class/net/$eth/queues/rx-$i/rps_cpus
    echo 4096(网卡buff)> /sys/class/net/$eth/queues/rx-$i/rps_flow_cnt
    2)CPU小于网卡队列个数,绑中断就可以,可以试着关闭RPS看一下效果:
    echo 0 > /sys/class/net/<dev>/queues/rx-<n>/rps_cpus
    

    4.numa CPU调整,对齐网卡位置,可以提高内核处理速度,从而给更多CPU给应用收包,减缓丢包概率;

    查看网卡numa位置:

    ethtool -i eth1|grep bus-info
    lspci -s bus-info -vv|grep node
    

    上面中断和RPS设置里面mask需要重新按numa CPU分配重新设置;

    5.可以试着开启中断聚合(看网卡是否支持)

    查看 : 

     ethtool -c ethx
    Coalesce parameters for eth1:
    Adaptive RX: on  TX: on
    stats-block-usecs: 0
    sample-interval: 0
    pkt-rate-low: 0
    pkt-rate-high: 0
    
    
    rx-usecs: 25
    rx-frames: 0
    rx-usecs-irq: 0
    rx-frames-irq: 256
    
    
    tx-usecs: 25
    tx-frames: 0
    tx-usecs-irq: 0
    tx-frames-irq: 256
    
    
    rx-usecs-low: 0
    rx-frame-low: 0
    tx-usecs-low: 0
    tx-frame-low: 0
    
    
    rx-usecs-high: 0
    rx-frame-high: 0
    tx-usecs-high: 0
    tx-frame-high: 0
    
    
    

    调整:

    ethtool -C ethx adaptive-rx on
    

    简单总结一下网卡驱动丢包处理:



    内核协议栈丢包

    以太网链路层丢包

    neighbor系统arp丢包

    arp_ignore配置丢包

    arp_ignore参数的作用是控制系统在收到外部的arp请求时,是否要返回arp响应。arp_ignore参数常用的取值主要有0,1,2,3~8较少用到;

    查看:sysctl -a|grep arp_ignore

    解决方案:根据实际场景设置对应值;

    0:响应任意网卡上接收到的对本机IP地址的arp请求(包括环回网卡上的地址),而不管该目的IP是否在接收网卡上。

    1:只响应目的IP地址为接收网卡上的本地地址的arp请求。

    2:只响应目的IP地址为接收网卡上的本地地址的arp请求,并且arp请求的源IP必须和接收网卡同网段。

    3:如果ARP请求数据包所请求的IP地址对应的本地地址其作用域(scope)为主机(host),则不回应ARP响应数据包,如果作用域为全局(global)或链路(link),则回应ARP响应数据包。

    arp_filter配置丢包

    在多接口系统里面(比如腾讯云的弹性网卡场景),这些接口都可以回应arp请求,导致对端有可能学到不同的mac地址,后续报文发送可能由于mac地址和接收报文接口mac地址不一样而导致丢包,arp_filter主要是用来适配这种场景;

    查看:

    sysctl -a | grep arp_filter
    

    解决方案: 

    根据实际场景设置对应的值,一般默认是关掉此过滤规则,特殊情况可以打开;
    0:默认值,表示回应arp请求的时候不检查接口情况;
    1:表示回应arp请求时会检查接口是否和接收请求接口一致,不一致就不回应;
    

    arp表满导致丢包

    比如下面这种情况,由于突发arp表项很多 超过协议栈默认配置,发送报文的时候部分arp创建失败,导致发送失败,从而丢包:

    查看:

    • 查看arp状态:cat /proc/net/stat/arp_cache ,table_fulls统计

    •  查看dmesg消息(内核打印):

    dmesg|grep neighbour
    neighbour: arp_cache: neighbor table overflow!
    
    • 查看当前arp表大小:ip n|wc -l

          查看系统配额:

    sysctl -a |grep net.ipv4.neigh.default.gc_thresh
    gc_thresh1:存在于ARP高速缓存中的最少层数,如果少于这个数,垃圾收集器将不会运行。缺省值是128。
    
    
    gc_thresh2 :保存在 ARP 高速缓存中的最多的记录软限制。垃圾收集器在开始收集前,允许记录数超过这个数字 5 秒。缺省值是 512。
    gc_thresh3 :保存在 ARP 高速缓存中的最多记录的硬限制,一旦高速缓存中的数目高于此,垃圾收集器将马上运行。缺省值是1024。
    

    一般在内存足够情况下,可以认为gc_thresh3 值是arp 表总大小;

    解决方案:根据实际arp最大值情况(比如访问其他子机最大个数),调整arp表大小

    $ sudo sysctl -w net.ipv4.neigh.default.gc_thresh1=1024
    $ sudo sysctl -w net.ipv4.neigh.default.gc_thresh2=2048
    $ sudo sysctl -w net.ipv4.neigh.default.gc_thresh3=4096
    $ sudo sysctl  -p
    

    arp请求缓存队列溢出丢包

    查看

    cat /proc/net/stat/arp_cache ,unresolved_discards是否有新增计数
    

    解决方案:根据客户需求调整缓存队列大小unres_qlen_bytes:



    网络IP层丢包

    接口ip地址配置丢包

    1. 本机服务不通,检查lo接口有没有配置地址是127.0.0.1;

    2 .本机接收失败, 查看local路由表:ip r show table local|grep 子机ip地址;这种丢包一般会出现在多IP场景,子机底层配置多ip失败,导致对应ip收不到包而丢包;

    解决方案:

    1.配置正确接口ip地址;比如ip a add 1.1.1.1 dev eth0 

    2.如果发现接口有地址还丢包,可能是local路由表没有对应条目,紧急情况下,可以用手工补上:

    比如ip r add local 本机ip地址 dev eth0 table local ;


    路由丢包

    路由配置丢包

    查看:

    1.查看配置 路由是否设置正确(是否可达),是否配置策略路由(在弹性网卡场景会出现此配置)ip rule:


    然后找到对应路由表。查看路由表:

    或者直接用 ip r get x.x.x.x,让系统帮你查找是否存在可达路由,接口是否符合预期;

    2.查看系统统计信息:  

    netstat -s|grep "dropped because of missing route"
    

    解决方案:重新配置正确的路由;

       


    反向路由过滤丢包

    反向路由过滤机制是Linux通过反向路由查询,检查收到的数据包源IP是否可路由(Loose mode)、是否最佳路由(Strict mode),如果没有通过验证,则丢弃数据包,设计的目的是防范IP地址欺骗攻击。

    查看:

    rp_filter提供三种模式供配置:

    0 - 不验证

    1 - RFC3704定义的严格模式:对每个收到的数据包,查询反向路由,如果数据包入口和反向路由出口不一致,则不通过

    2 - RFC3704定义的松散模式:对每个收到的数据包,查询反向路由,如果任何接口都不可达,则不通过

    查看当前rp_filter策略配置:

    $cat /proc/sys/net/ipv4/conf/eth0/rp_filter

    如果这里设置为1,就需要查看主机的网络环境和路由策略是否可能会导致客户端的入包无法通过反向路由验证了。

    从原理来看这个机制工作在网络层,因此,如果客户端能够Ping通服务器,就能够排除这个因素了。

    解决方案:

    根据实际网络环境将rp_filter设置为0或2:

    $ sysctl -w net.ipv4.conf.all.rp_filter=2或
    $ sysctl -w net.ipv4.conf.eth0.rp_filter=2
    


    防火墙丢包

    客户设置规则导致丢包

    查看:

      iptables -nvL |grep DROP ;
    

    解决方案:  修改防火墙规则;


    连接跟踪导致丢包

    连接跟踪表溢出丢包

    kernel 用 ip_conntrack 模块来记录 iptables 网络包的状态,并把每条记录保存到 table 里(这个 table 在内存里,可以通过/proc/net/ip_conntrack 查看当前已经记录的总数),如果网络状况繁忙,比如高连接,高并发连接等会导致逐步占用这个 table 可用空间,一般这个 table 很大不容易占满并且可以自己清理,table 的记录会一直呆在 table 里占用空间直到源 IP 发一个 RST 包,但是如果出现被攻击、错误的网络配置、有问题的路由/路由器、有问题的网卡等情况的时候,就会导致源 IP 发的这个 RST 包收不到,这样就积累在 table 里,越积累越多直到占满。无论,哪种情况导致table变满,满了以后就会丢包,出现外部无法连接服务器的情况。内核会报如下错误信息:kernel: ip_conntrack: table full, dropping packet;

    查看当前连接跟踪数 :

    cat /proc/sys/net/netfilter/nf_conntrack_max
    

    解决方案:

    增大跟踪的最大条数
    net.netfilter.nf_conntrack_max  = 3276800
    减少跟踪连接的最大有效时间
    net.netfilter.nf_conntrack_tcp_timeout_established = 1200
    net.netfilter.nf_conntrack_udp_timeout_stream = 180
    net.netfilter.nf_conntrack_icmp_timeout = 30
    

    ct创建冲突失导致丢包

    查看:当前连接跟踪统计:cat /proc/net/stat/nf_conntrack,可以查各种ct异常丢包统计

    解决方案:内核热补丁修复或者更新内核版本(合入补丁修改);


    传输层UDP/TCP丢包

    tcp 连接跟踪安全检查丢包

    丢包原因:由于连接没有断开,但服务端或者client之前出现过发包异常等情况(报文没有经过连接跟踪模块更新窗口计数),没有更新合法的window范围,导致后续报文安全检查被丢包;协议栈用nf_conntrack_tcp_be_liberal 来控制这个选项:

    1:关闭,只有不在tcp窗口内的rst包被标志为无效;

    0:开启;   所有不在tcp窗口中的包都被标志为无效;

    查看: 

    查看配置 :

    sysctl -a|grep nf_conntrack_tcp_be_liberal 
    net.netfilter.nf_conntrack_tcp_be_liberal = 1
    

    查看log:

    一般情况下netfiler模块默认没有加载log,需要手动加载;

    modprobe ipt_LOG11
    sysctl -w net.netfilter.nf_log.2=ipt_LOG
    

    然后发包后在查看syslog;

    解决方案:根据实际抓包分析情况判断是不是此机制导致的丢包,可以试着关闭试一下;

    分片重组丢包

    情况总结:超时

    查看:

    netstat -s|grep timeout
    601 fragments dropped after timeout
    

    解决方法:调整超时时间

    net.ipv4.ipfrag_time = 30
    sysctl -w net.ipv4.ipfrag_time=60
    

    frag_high_thresh, 分片的内存超过一定阈值会导致系统安全检查丢包

    查看:

    netstat -s|grep reassembles
    8094 packet reassembles failed
    

    解决方案:调整大小

    net.ipv4.ipfrag_high_thresh 
    net.ipv4.ipfrag_low_thresh
    

    分片安全距检查离丢包

    查看:

    netstat -s|grep reassembles
    8094 packet reassembles failed
    

    解决方案: 把ipfrag_max_dist设置为0,就关掉此安全检查

    pfrag_max_dist特性,在一些场景下其实并不适用:

    1.有大量的网络报文交互

    2.发送端的并发度很高,同时SMP架构,导致很容易造成这种乱序情况;

    分片hash bucket冲突链太长超过系统默认值128

    查看: 

    dmesg|grep “Dropping fragment”
    inet_frag_find: Fragment hash bucket 128 list length grew over limit. Dropping fragment.
    

    解决方案:热补丁调整hash大小;

    系统内存不足,创建新分片队列失败

    查看方法:

    netstat -s|grep reassembles
    8094 packet reassembles failed
    

    dropwatch查看丢包位置 :

    解决方案:

    a.增大系统网络内存:

    net.core.rmem_default 
    net.core.rmem_max 
    net.core.wmem_default
    

    b.系统回收内存:

    紧急情况下,可以用 /proc/sys/vm/drop_caches, 去释放一下虚拟内存;

    To free pagecache:
    # echo 1 > /proc/sys/vm/drop_caches
    To free dentries and inodes:
    # echo 2 > /proc/sys/vm/drop_caches
    To free pagecache, dentries and inodes:
    echo 3 > /proc/sys/vm/drop_caches
    


    MTU丢包

    查看:

    1.检查接口MTU配置,ifconfig eth1/eth0,默认是1500;

    2.进行MTU探测,然后设置接口对应的MTU值;

    解决方案:

    1. 根据实际情况,设置正确MTU值;

    2. 设置合理的tcp mss,启用TCP MTU Probe:

    cat /proc/sys/net/ipv4/tcp_mtu_probing:
    tcp_mtu_probing - INTEGER Controls TCP Packetization-Layer Path MTU Discovery.
    Takes three values:
    0 - Disabled 
    1 - Disabled by default, enabled when an ICMP black hole detected
    2 - Always enabled, use initial MSS of tcp_base_mss.
    

    tcp层丢包

    TIME_WAIT过多丢包

    大量TIMEWAIT出现,并且需要解决的场景,在高并发短连接的TCP服务器上,当服务器处理完请求后立刻按照主动正常关闭连接。。。这个场景下,会出现大量socket处于TIMEWAIT状态。如果客户端的并发量持续很高,此时部分客户端就会显示连接不上;

    查看:

    查看系统log :

    dmsg
    TCP: time wait bucket table overflow;
    

    查看系统配置:

    sysctl -a|grep tcp_max_tw_buckets
    net.ipv4.tcp_max_tw_buckets = 16384
    

    解决方案:

    1. tw_reuse,tw_recycle 必须在客户端和服务端timestamps 开启时才管用(默认打开)

    2. tw_reuse 只对客户端起作用,开启后客户端在1s内回收;

    3. tw_recycle对客户端和服务器同时起作用,开启后在3.5*RTO 内回收,RTO 200ms~ 120s具体时间视网络状况。内网状况比tw_reuse稍快,公网尤其移动网络大多要比tw_reuse 慢,优点就是能够回收服务端的TIME_WAIT数量;

    在服务端,如果网络路径会经过NAT节点,不要启用net.ipv4.tcp_tw_recycle,会导致时间戳混乱,引起其他丢包问题;

    4. 调整tcp_max_tw_buckets大小,如果内存足够:

    sysctl -w net.ipv4.tcp_max_tw_buckets=163840;
    

    时间戳异常丢包

    当多个客户端处于同一个NAT环境时,同时访问服务器,不同客户端的时间可能不一致,此时服务端接收到同一个NAT发送的请求,就会出现时间戳错乱的现象,于是后面的数据包就被丢弃了,具体的表现通常是是客户端明明发送的SYN,但服务端就是不响应ACK。在服务器借助下面的命令可以来确认数据包是否有不断被丢弃的现象。

    检查:

    netstat -s | grep rejects
    
    
    

    解决方案:

    如果网络路径会经过NAT节点,不要启用net.ipv4.tcp_tw_recycle;

    TCP队列问题导致丢包

    原理:

    tcp状态机(三次握手)


     协议处理:

    一个是半连接队列(syn queue):

    在三次握手协议中,服务器维护一个半连接队列,该队列为每个客户端的SYN包开设一个条目(服务端在接收到SYN包的时候,就已经创建了request_sock结构,存储在半连接队列中),该条目表明服务器已收到SYN包,并向客户发出确认,正在等待客户的确认包(会进行第二次握手发送SYN+ACK的包加以确认)。这些条目所标识的连接在服务器处于Syn_RECV状态,当服务器收到客户的确认包时,删除该条目,服务器进入ESTABLISHED状态。该队列为SYN队列,长度为max(64,/proc/sys/net/ipv4/tcp_max_syn_backlog),  机器的tcp_max_syn_backlog值在/proc/sys/net/ipv4/tcp_max_syn_backlog下配置;

    一个是全连接队列(accept queue):

    第三次握手时,当server接收到ACK 报之后, 会进入一个新的叫 accept 的队列,该队列的长度为 min(backlog, somaxconn),默认情况下,somaxconn 的值为 128,表示最多有 129 的 ESTAB 的连接等待 accept(),而 backlog 的值则应该是由 int listen(int sockfd, int backlog) 中的第二个参数指定,listen 里面的 backlog 可以有我们的应用程序去定义的;

    查看:

    连接建立失败,syn丢包:

    netstat -s |grep -i listen
    SYNs to LISTEN sockets dropped
    

    也会受到连接满丢包影响

    解决方案: 增加大小 tcp_max_syn_backlog

    连接满丢包

    -xxx times the listen queue of a socket overflowed

    查看:

    • 查看accept队列大小 :net.core.somaxconn

    • ss -lnt查询socket队列 :LISTEN 状态: Recv-Q 表示的当前等待服务端调用 accept 完成三次握手的 listen backlog 数值,也就是说,当客户端通过 connect() 去连接正在 listen() 的服务端时,这些连接会一直处于这个 queue 里面直到被服务端 accept();Send-Q 表示的则是最大的 listen backlog 数值,这就就是上面提到的 min(backlog, somaxconn) 的值,

    • 看一下是不是应用程序设置限制, int listen(int sockfd, int backlog);

    解决方案:

    •  Linux内核参进行优化,可以缓解压力 tcp_abort_on_overflow=1

    •  调整net.core.somaxconn大小;

    •  应用程序设置问题,通知客户程序修改;

    syn flood攻击丢包

      目前,Linux下默认会进行5次重发SYN-ACK包,重试的间隔时间从1s开始,下次的重试间隔时间是前一次的双倍,5次的重试时间间隔为1s, 2s, 4s, 8s, 16s,总共31s,第5次发出后还要等32s都知道第5次也超时了,所以,总共需要 1s + 2s + 4s+ 8s+ 16s + 32s = 63s,TCP才会把断开这个连接。由于,SYN超时需要63秒,那么就给攻击者一个攻击服务器的机会,攻击者在短时间内发送大量的SYN包给Server(俗称 SYN flood 攻击),用于耗尽Server的SYN队列。对于应对SYN 过多的问题;

    查看:  查看syslog:  kernel: [3649830.269068] TCP: Possible SYN flooding on port xxx. Sending cookies. Check SNMP counters.

    解决方案:

    • 增大tcp_max_syn_backlog

    • 减少tcp_synack_retries

    • 启用tcp_syncookies

    • 启用tcp_abort_on_overflow, tcp_abort_on_overflow修改成 1,1表示第三步的时候如果全连接队列满了,server发送一个reset包给client,表示废掉这个握手过程和这个连接(本来在server端这个连接就还没建立起来);

    PAWS机制丢包

    原理:PAWS(Protect Against Wrapped Sequence numbers),高带宽下,TCP序列号可能在较短的时间内就被重复使用(recycle/wrapped)
    就可能导致同一条TCP流在短时间内出现序号一样的两个合法的数据包及其确认包。

    查看:

    $netstat -s |grep -e "passive connections rejected because of time 
    stamp" -e "packets rejects in established connections because of 
    timestamp” 
    387158 passive connections rejected because of time stamp
    825313 packets rejects in established connections because of timestamp
    

    通过sysctl查看是否启用了tcp_tw_recycle及tcp_timestamp:

    $ sysctl net.ipv4.tcp_tw_recycle
    net.ipv4.tcp_tw_recycle = 1 
    $ sysctl net.ipv4.tcp_timestamps
    net.ipv4.tcp_timestamps = 1
    

    1. tcp_tw_recycle参数。它用来快速回收TIME_WAIT连接,不过如果在NAT环境下会引发问题;

    2. 当多个客户端通过NAT方式联网并与服务端交互时,服务端看到的是同一个IP,也就是说对服务端而言这些客户端实际上等同于一个,可惜由于这些客户端的时间戳可能存在差异,于是乎从服务端的视角看,便可能出现时间戳错乱的现象,进而直接导致时间戳小的数据包被丢弃。如果发生了此类问题,具体的表现通常是是客户端明明发送的SYN,但服务端就是不响应ACK。

    解决方案: 

    在NAT环境下,清除tcp时间戳选项,或者不开启tcp_tw_recycle参数;

    TLP问题丢包

    TLP主要是为了解决尾丢包重传效率的问题,TLP能够有效的避免较长的RTO超时,进而提高TCP性能,详细参考文章:

    http://perthcharles.github.io/2015/10/31/wiki-network-tcp-tlp/;

    但在低时延场景下(短连接小包量),TLP与延迟ACK组合可能会造成无效重传,导致客户端感发现大量假重传包,加大了响应延迟;

    查看:

    查看协议栈统计:

    netstat -s |grep TCPLossProbes
    

    查看系统配置:

     sysctl -a | grep tcp_early_retrans
    


    解决方案:

    1.关掉延迟ack,打开快速ack;

    2.linux实现nodelay语意不是快速ack,只是关闭nagle算法;

    3.打开快速ack选项,socket里面有个 TCP_QUICKACK 选项, 需要每次recv后再设置一次。

    内存不足导致丢包

    查看:

    查看log:

    dmesg|grep “out of memory”
    

    查看系统配置: 

    cat /proc/sys/net/ipv4/tcp_mem
    cat /proc/sys/net/ipv4/tcp_rmem
    cat /proc/sys/net/ipv4/tcp_wmem
    

    解决方案:

    根据TCP业务并发流量,调整系统参数,一般试着增大2倍或者其他倍数来看是否缓解;

    sysclt -w net.ipv4.tcp_mem=
    sysclt -w net.ipv4.tcp_wmem=
    sysclt -w net.ipv4.tcp_rmem=
    sysctl -p
    

    TCP超时丢包

    查看:

    抓包分析一下网络RTT:

    用其他工具测试一下当前端到端网络质量(hping等);

    # hping -S 9.199.10.104 -A
    HPING 9.199.10.104 (bond1 9.199.10.104): SA set, 40 headers + 0 data bytes
    len=46 ip=9.199.10.104 ttl=53 DF id=47617 sport=0 flags=R seq=0 win=0 rtt=38.3 ms
    len=46 ip=9.199.10.104 ttl=53 DF id=47658 sport=0 flags=R seq=1 win=0 rtt=38.3 ms
    len=46 ip=9.199.10.104 ttl=53 DF id=47739 sport=0 flags=R seq=2 win=0 rtt=30.4 ms
    len=46 ip=9.199.10.104 ttl=53 DF id=47842 sport=0 flags=R seq=3 win=0 rtt=30.4 ms
    len=46 ip=9.199.10.104 ttl=53 DF id=48485 sport=0 flags=R seq=4 win=0 rtt=38.7 ms
    len=46 ip=9.199.10.104 ttl=53 DF id=49274 sport=0 flags=R seq=5 win=0 rtt=34.1 ms
    len=46 ip=9.199.10.104 ttl=53 DF id=49491 sport=0 flags=R seq=6 win=0 rtt=30.3 ms
    

    解决方案:

    • 关闭Nagle算法,减少小包延迟;

    • 关闭延迟ack:

      sysctl -w net.ipv4.tcp_no_delay_ack=1
    

    TCP乱序丢包

    此时TCP会无法判断是数据包丢失还是乱序,因为丢包和乱序都会导致接收端收到次序混乱的数据包,造成接收端的数据空洞。TCP会将这种情况暂定为数据包的乱序,因为乱序是时间问题(可能是数据包的迟到),而丢包则意味着重传。当TCP意识到包出现乱序的情况时,会立即ACK,该ACK的TSER部分包含的TSEV值会记录当前接收端收到有序报文段的时刻。这会使得数据包的RTT样本值增大,进一步导致RTO时间延长。这对TCP来说无疑是有益的,因为TCP有充分的时间判断数据包到底是失序还是丢了来防止不必要的数据重传。当然严重的乱序则会让发送端以为是丢包一旦重复的ACK超过TCP的阈值,便会触发超时重传机制,以及时解决这种问题;详细请参考博客:

    https://blog.csdn.net/dog250/article/details/78692585

    查看:抓包分析是否存在很多乱序报文:

    解决方案:如果在多径传输场景或者网络质量不好,可以通过修改下面值来提供系统对TCP无序传送的容错率:



    拥塞控制丢包

    在互联网发展的过程当中,TCP算法也做出了一定改变,先后演进了

    Reno、NewReno、Cubic和Vegas,这些改进算法大体可以分为基于丢包和基于延时的拥塞控制算法。基于丢包的拥塞控制算法以Reno、NewReno为代表,它的主要问题有Buffer bloat和长肥管道两种,基于丢包的协议拥塞控制机制是被动式的,其依据网络中的丢包事件来做网络拥塞判断。即使网络中的负载很高,只要没有产生拥塞丢包,协议就不会主动降低自己的发送速度。最初路由器转发出口的Buffer 是比较小的,TCP在利用时容易造成全局同步,降低带宽利用率,随后路由器厂家由于硬件成本下降不断地增加Buffer,基于丢包反馈的协议在不丢包的情况下持续占用路由器buffer,虽然提高了网络带宽的利用率,但同时也意味着发生拥塞丢包后,网络抖动性加大。另外对于带宽和RTT都很高的长肥管道问题来说,管道中随机丢包的可能性很大,TCP的默认buffer设置比较小加上随机丢包造成的cwnd经常下折,导致带宽利用率依旧很低;  BBR(Bottleneck Bandwidth and Round-trip propagation time)是一种基于带宽和延迟反馈的拥塞控制算法。目前已经演化到第二版,是一个典型的封闭反馈系统,发送多少报文和用多快的速度发送这些报文都是在每次反馈中不断调节。在BBR提出之前,拥塞控制都是基于事件的算法,需要通过丢包或延时事件驱动;BBR提出之后,拥塞控制是基于反馈的自主自动控制算法,对于速率的控制是由算法决定,而不由网络事件决定,BBR算法的核心是找到最大带宽(Max BW)和最小延时(Min RTT)这两个参数,最大带宽和最小延时的乘积可以得到BDP(Bandwidth Delay Product), 而BDP就是网络链路中可以存放数据的最大容量。BDP驱动Probing State Machine得到Rate quantum和cwnd,分别设置到发送引擎中就可以解决发送速度和数据量的问题。

    Linux 4.9内核首次采用BBR拥塞控制算法第一个版本,BBR抗丢包能力比其他算法要强,但这个版本在某些场景下面有问题(缺点),BBR在实时音视频领域存在的问题,深队列竞争不过Cubic。

    问题现象就是:在深队列场景,BBR的ProbeRTT阶段只发4个包,发送速率下降太多会引发延迟加大和卡顿问题。

    查看:

    ss -sti //在源端 ss -sti|grep 10.125.42.49:47699 -A 3 ( 10.125.42.49:47699 是目的端地址和端口号)
    

    解决方案:

    • ProbeRTT并不适用实时音视频领域,因此可以选择直接去除,或者像BBRV2把probe RTT缩短到2.5s一次,使用0.5xBDP发送;

    • 如果没有特殊需求,切换成稳定的cubic算法;


    UDP层丢包

    收发包失败丢包

    查看:netstat 统计

    如果有持续的 receive buffer errors/send buffer errors 计数;

    解决方案:

    1. CPU负载(多核绑核配置),网络负载(软中断优化,调整驱动队列netdev_max_backlog),内存配置(协议栈内存);

    2. 按峰值在来,增大buffer缓存区大小:

    net.ipv4.udp_mem = xxx
    net.ipv4.udp_rmem_min = xxx
    net.ipv4.udp_wmem_min = xxx
    

         3. 调整应用设计:

    • UDP本身就是无连接不可靠的协议,适用于报文偶尔丢失也不影响程序状态的场景,比如视频、音频、游戏、监控等。对报文可靠性要求比较高的应用不要使用 UDP,推荐直接使用 TCP。当然,也可以在应用层做重试、去重保证可靠性

    • 如果发现服务器丢包,首先通过监控查看系统负载是否过高,先想办法把负载降低再看丢包问题是否消失

    • 如果系统负载过高,UDP丢包是没有有效解决方案的。如果是应用异常导致CPU、memory、IO 过高,请及时定位异常应用并修复;如果是资源不够,监控应该能及时发现并快速扩容

    • 对于系统大量接收或者发送UDP报文的,可以通过调节系统和程序的 socket buffer size 来降低丢包的概率

    • 应用程序在处理UDP报文时,要采用异步方式,在两次接收报文之间不要有太多的处理逻辑



    应用层socket丢包

    socket缓存区接收丢包

    查看:  

    1. 抓包分析是否存在丢包情况;

    2. 查看统计:

    netstat -s|grep "packet receive errors"
    

    解决方案:

    调整socket缓冲区大小:

    socket配置(所有协议socket):
    # Default Socket Receive Buffer
    net.core.rmem_default = 31457280
    # Maximum Socket Receive Buffer
    net.core.rmem_max = 67108864
    
    
    

    具体大小调整原理:

    缓冲区大小没有任何设置值是最佳的,因为最佳大小随具体情况而不同

    缓冲区估算原理:在数据通信中,带宽时延乘积(英语:bandwidth-delay product;或称带宽延时乘积、带宽延时积等)指的是一个数据链路的能力(每秒比特)与来回通信延迟(单位秒)的乘积。[1][2]其结果是以比特(或字节)为单位的一个数据总量,等同在任何特定时间该网络线路上的最大数据量——已发送但尚未确认的数据。

    BDP =  带宽 * RTT

    可以通过计算当面节点带宽和统计平均时延来估算BDP,即缓冲区的大小,可以参考下面常见场景估计:

    参考:https://docs.oracle.com/cd/E56344_01/html/E53803/gnkor.html

    应用设置tcp连接数大小丢包

    查看:

    请参考上面TCP连接队列分析;

    解决方案:

    设置合理的连接队列大小,当第三次握手时,当server接收到ACK 报之后, 会进入一个新的叫 accept 的队列,该队列的长度为 min(backlog, somaxconn),默认情况下,somaxconn 的值为 128,表示最多有 129 的 ESTAB 的连接等待 accept(),而 backlog 的值则应该是由 int listen(int sockfd, int backlog) 中的第二个参数指定,listen 里面的 backlog 可以有我们的应用程序去定义的;

    应用发送太快导致丢包

    查看统计:

     netstat -s|grep "send buffer errors
    

    解决方案:

    • ICMP/UDP没有流控机制,需要应用设计合理发送方式和速度,照顾到底层buff大小和CPU负载以及网络带宽质量;

    •  设置合理的sock缓冲区大小:

       setsockopt(s,SOL_SOCKET,SO_SNDBUF,  i(const char*)&nSendBuf,sizeof(int));
    
    • 调整系统socket缓冲区大小:

       # Default Socket Send Buffer
       net.core.wmem_default = 31457280
       # Maximum Socket Send Buffer
       net.core.wmem_max = 33554432
    

    附:简单总结一下内核协议栈丢包

    相关工具介绍

    1.dropwatch工具

    原理:  监听 kfree_skb(把网络报文丢弃时会调用该函数)函数或者事件吗,然后打印对应调用堆栈;想要详细了解 linux 系统在执行哪个函数时丢包的话,可以使用 dropwatch 工具,它监听系统丢包信息,并打印出丢包发生的函数:

    2. tcpdump工具

    原理: tcpdump 是一个Unix下一个功能强大的网络抓包工具,它允许用户拦截和显示发送或收到过网络连接到该计算机的TCP/IP和其他数据包

    抓包命令参考:

    https://www.tcpdump.org/manpages/tcpdump.1.html

    数据包分析:

    1.用wireshark工具分析  参考:Wireshark数据包分析实战.pdf

    2.可以转化生成CSV数据,用Excel或者shell去分析特定场景报文;

    3.可以在linux上用tshark命令行工具进行分析:

    https://www.wireshark.org/docs/man-pages/tshark.html

    总结

    本文只是分析大部分可能会丢包节点,提供了单个节点丢包排查和相关的解决方案, 丢包问题牵扯网络链路各个组件,尤其是在云网络时代,网络拓扑复杂多变,涉及运营商网络,IDC网络,专线等underlay网络,边界网关,VPC网络,CLB负载均衡等云上overlay网络,各种丢包问题排障起来非常复杂且困难,但掌握网络通信基本原理后,可以分解网络拓扑,对通信节点进行逐一排查,也可以找到丢包位置,后续会更加深入介绍云计算时代,云上网络丢包排查方法,网络架构解析等,达到任何丢包问题都可以快速排查和定位解决,帮助客户快速恢复业务,下期再会。

      看到最后的朋友都是缘分~关注公众号,后台回复丢包获取精简版脑图

    更多精彩,尽在"Linux阅码场",扫描下方二维码关注

    别忘了分享、点赞或者在看哦~

    展开全文
  • 网络丢包排查思路

    千次阅读 2020-03-18 18:28:56
    网络丢包排查思路 1.防火墙确认:看防火墙是否配置了DROP特定端口范围的可能性 方法:查看iptables filter表,确认是否有相应规则会导致此丢包行为,命令:sudoiptables-save-tfilter 2.连接跟踪表溢出 除了防火墙...

    网络丢包排查思路


    1.防火墙确认:

    看防火墙是否配置了DROP特定端口范围的可能性
    方法:查看iptables filter表,确认是否有相应规则会导致此丢包行为,命令: sudo iptables-save -t filter

    2.连接跟踪表溢出


    除了防火墙本身配置DROP规则外,与防火墙有关的还有连接跟踪表nf_conntrack,Linux为每个经过内核网络栈的数据包,生成一个新的连接记录项,当服务器处理的连接过多时,连接跟踪表被打满,服务器会丢弃新建连接的数据包。
    1)问题确认:通过dmesg可以确认是否有该情况发生:
        命令:dmesg |grep nf_conntrack,如果输出值中有“nf_conntrack: table full, dropping packet”,说明服务器nf_conntrack表已经被打满。
    通过/proc文件系统查看nf_conntrack表实时状态:
    # 查看nf_conntrack表最大连接数
    $ cat /proc/sys/net/netfilter/nf_conntrack_max
    65536
    # 查看nf_conntrack表当前连接数
    $ cat /proc/sys/net/netfilter/nf_conntrack_count
    7611
    2)解决办法:如果确认服务器因连接跟踪表溢出而开始丢包,首先需要查看具体连接判断是否正遭受DOS攻击,如果是正常的业务流量造成,可以考虑调整nf_conntrack的参数:
    nf_conntrack_max决定连接跟踪表的大小,默认值是65535,可以根据系统内存大小计算一个合理值:CONNTRACK_MAX = RAMSIZE(in bytes)/16384/(ARCH/32),如32G内存可以设置1048576;
    nf_conntrack_buckets决定存储conntrack条目的哈希表大小,默认值是nf_conntrack_max的1/4,延续这种计算方式:BUCKETS = CONNTRACK_MAX/4,如32G内存可以设置262144;
    nf_conntrack_tcp_timeout_established决定ESTABLISHED状态连接的超时时间,默认值是5天,可以缩短到1小时,即3600。
    命令行配置:
    $ sysctl -w net.netfilter.nf_conntrack_max=1048576
    $ sysctl -w net.netfilter.nf_conntrack_buckets=262144
    $ sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=3600

    3.Ring Buffer溢出


    排除了防火墙的因素,我们从底向上来看Linux接收数据包的处理过程,首先是网卡驱动层。
    物理介质上的数据帧到达后首先由NIC(网络适配器)读取,写入设备内部缓冲区Ring Buffer中,再由中断处理程序触发Softirq从中消费,Ring Buffer的大小因网卡设备而异。当网络数据包到达(生产)的速率快于内核处理(消费)的速率时,Ring Buffer很快会被填满,新来的数据包将被丢弃。
           1)判断方法:通过ethtool或/proc/net/dev可以查看因Ring Buffer满而丢弃的包统计,在统计项中以fifo标识:
    $ ethtool -S eth0|grep rx_fifo
        rx_fifo_errors: 0
    $ cat /proc/net/dev
        Inter-|   Receive                                                |  Transmit
    可以看到服务器的接收方向的fifo丢包数并没有增加,说明此阶段不存在丢包。
         2)如果是,解决办法:
    如果发现服务器上某个网卡的fifo数持续增大,可以去确认CPU中断是否分配均匀,也可以尝试增加Ring Buffer的大小,通过ethtool可以查看网卡设备Ring Buffer最大值,修改Ring Buffer当前设置:
    查看eth0网卡Ring Buffer最大值和当前设置
    $ ethtool -g eth0
    Ring parameters for eth0:
     
    Pre-set maximums:
    RX:     4096  
    RX Mini:    0
    RX Jumbo:   0
    TX:     4096  
    Current hardware settings:
    RX:     1024  
    RX Mini:    0
    RX Jumbo:   0
    TX:     1024  
    # 修改网卡eth0接收与发送硬件缓存区大小
    $ ethtool -G eth0 rx 4096 tx 4096
    Pre-set maximums:
    RX:     4096  
    RX Mini:    0
    RX Jumbo:   0
    TX:     4096  
    Current hardware settings:
    RX:     4096  
    RX Mini:    0
    RX Jumbo:   0
    TX:     4096


    4.netdev_max_backlog溢出


    netdev_max_backlog是内核从NIC收到包后,交由协议栈(如IP、TCP)处理之前的缓冲队列。每个CPU核都有一个backlog队列,与Ring Buffer同理,当接收包的速率大于内核协议栈处理的速率时,CPU的backlog队列不断增长,当达到设定的netdev_max_backlog值时,数据包将被丢弃。
          
    1)判断方法: 通过查看/proc/net/softnet_stat可以确定是否发生了netdev backlog队列溢出:
    其中:


        每一行代表每个CPU核的状态统计,从CPU0依次往下;
    每一列代表一个CPU核的各项统计:第一列代表中断处理程序收到的包总数;第二列即代表由于netdev_max_backlog队列溢出而被丢弃的包总数。
    从上面的输出可以看出,这台服务器统计中,并没有因为netdev_max_backlog导致的丢包。
    2)解决办法
    netdev_max_backlog的默认值是1000,在高速链路上,可能会出现上述第二列统计不为0的情况,可以通过修改内核参数net.core.netdev_max_backlog来解决:
        sysctl -w net.core.netdev_max_backlog=2000

    5.反向路由过滤

    反向路由过滤机制是Linux通过反向路由查询,检查收到的数据包源IP是否可路由(Loose mode)、是否最佳路由(Strict mode),如果没有通过验证,则丢弃数据包,设计的目的是防范IP地址欺骗攻击。rp_filter提供了三种模式供配置:
    0 - 不验证
    1 - RFC3704定义的严格模式:对每个收到的数据包,查询反向路由,如果数据包入口和反向路由出口不一致,则不通过
    2 - RFC3704定义的松散模式:对每个收到的数据包,查询反向路由,如果任何接口都不可达,则不通过
    1)如何确认
    查看当前rp_filter策略配置:
    $ cat /proc/sys/net/ipv4/conf/eth0/rp_filter
    0
    如果这里设置为1,就需要查看主机的网络环境和路由策略是否可能会导致客户端的入包无法通过反向路由验证了。
    从原理来看这个机制工作在网络层,因此,如果客户端能够Ping通服务器,就能够排除这个因素了。
    2)如何解决
    根据实际网络环境将rp_filter设置为0或2:
    $ sysctl -w net.ipv4.conf.all.rp_filter=2
     或
     $ sysctl -w net.ipv4.conf.eth0.rp_filter=2


    6.半连接队列溢出

    半连接队列指的是TCP传输中服务器收到SYN包但还未完成三次握手的连接队列,队列大小由内核参数tcp_max_syn_backlog定义。
    当服务器保持的半连接数量达到tcp_max_syn_backlog后,内核将会丢弃新来的SYN包。
    1)如何确认
    通过dmesg可以确认是否有该情况发生:
    $ dmesg | grep "TCP: drop open request from"
    半连接队列的连接数量可以通过netstat统计SYN_RECV状态的连接得知
    2)如何解决
    tcp_max_syn_backlog的默认值是256,通常推荐内存大于128MB的服务器可以将该值调高至1024,内存小于32MB的服务器调低到128,同样,该参数通过sysctl修改:netstat -ant|grep SYN_RECV|wc -l
    sysctl -w net.ipv4.tcp_max_syn_backlog=1024
    另外,上述行为受到内核参数tcp_syncookies的影响,若启用syncookie机制,当半连接队列溢出时,并不会直接丢弃SYN包,而是回复带有syncookie的SYC+ACK包,设计的目的是防范SYN Flood造成正常请求服务不可用。


     

    展开全文
  • 一次网络丢包问题排查的经历

    千次阅读 2019-09-06 10:25:18
    如此长的延迟已经严重影响了性能测试的结果。由于负责现场测试的同事对网络不是十分的熟悉,所以想让我帮忙排查一下。事情紧急,二话不说,动手。 首先看了一下他们的日志,发现并不是所有的消息延迟都很大,只有一...

    前两天,有一个同事跑来找我帮忙。说他们项目现场出现了一个奇怪的事情。在做性能测试的时候,发现偶尔会出现消息延迟增大的问题,有时候一条消息发出去,需要5秒钟才能够被对方收到。如此长的延迟已经严重影响了性能测试的结果。由于负责现场测试的同事对网络不是十分的熟悉,所以想让我帮忙排查一下。事情紧急,二话不说,动手。

    首先看了一下他们的日志,发现并不是所有的消息延迟都很大,只有一小部分会出现这种情况。而且出现延迟的消息从业务功能上来讲没有什么关联性。再加上他们之前在实验室进行性能测试的时候,并没有出现这种问题。因此排除了是软件的原因。那么终点需要怀疑的就是网络的问题了。

    于是,第一感觉,可能有网络丢包,于是ping了一下对方服务器,果然,在长ping之下,有大约30%的包丢失了。那么问题的解决就有了方向。下一步就是看为什么会出现丢包了。

    紧接着按照原则分段定位。现场的网络结构大致是这样的,我方服务器->我方交换机->客户交换机->客户服务器。 于是,分段ping一下,发现从我方服务器到对端服务器丢包,从我方服务器到我方交换机不丢包。 从我方交换机到对端服务器也不丢包。 这下基本可以确定问题出现在我方服务器到我方交换机这一段了。 丢包的原因有很多,有简单的有复杂的。 自然先从简单的开始排查了。 先排除硬件问题。 换端口,换交换机,换网线,换网卡,换换换换能换的统统换了一遍。结果呢,问题依旧。那么就排除了硬件问题了。

    下一步考虑网络配置的问题,由于现场采用了两台交换机堆叠成一台交换机的技术,以前堆叠交换机都是专门的三方网络工程师配置的,而这次是自己人配置的,这位同事是新学的网络配置,新手按照手册配置的。 因此怀疑这里可能有问题。于是关闭了堆叠交换机中的一台,问题依旧。 

    原本想按照最小化原则,把交换机上的其他东西都拔掉,但是考虑到现场还有其他系统再测试,再加上主要怀疑对象是在交换机配置上,所以就没有动手拔线。

    这个时候想到了检测一下服务器的路由信息是不是有问题,于是用traceroute 命令探测了一下到对端服务器的地址。多次运行后发现,tranceroute居然给出了2中不同的路由。 第一跳有时候是网关,有时候不是网关而是一个未知的 * * *.  这就怪了,网关有问题?

    ping了一下网关,发现到网关却没有丢包。由于网关是配置在交换机上的,所以还是怀疑交换机的配置有问题。于是想看一下网关的MAC地址,看看网关是怎么配置的。于是在服务器上用arp 命令查看了网关,我晕,这一看不要紧,发现网关的MAC地址居然在不断的变化,一会儿是交换机管理地址的MAC一会儿是另外一个MAC.  同一个IP MAC居然会变,难道是ARP攻击? 可这是客户内网啊,而且是新建系统,arp共计的可能性不大。 那么最大的可能就是 IP地址冲突!!!

    我们的设备都是我们自己配置的IP自然不可能是我们自己导致的。于是又回到了先前的路上,最小化原则。 通知了其他测试系统暂停一下。 先拔掉了和客户交换机连接的网线,问题依旧。然后拔掉了和下面一个设备厂商的子网对接的网线,果然,问题消失了。 然后呢?然后再插上,问题又出现了。 就是他们呀,总算是逮到他们了。于是赶紧找他们的负责人一问,无语呀无语,他们为了自己方便,没有按照我们的网络规划,自己在下面接了一个路由器,还配了一个和网关一模一样的地址。于是乎,麻烦就出现了。

    其实本次解决问题没有什么特别的技术含量。只是网络丢包这种常见的问题,真的要算起来,原因太多,查起来比较麻烦。所以把这次的排查过程记录一下,留个纪念,也给需要的人一点参考。

    总结一下,基本的排查原则:首先是定位,分段去查找,找到问题存在的那一段。然后是最小化(这个应该先做的,这次被其他因素影响后做了,不然早就就决问题了),这两步的目的呢,都是把问题减少到最小的范围,然后再去检查。就比较容易了。定位到最小范围后,首先考虑硬件(因为这个容易查),然后呢就是配置部分的问题了。

    展开全文
  • 网络丢包的四大原因和修复方法

    千次阅读 2020-09-07 13:10:02
    网络丢包的四大原因和修复方法   MIKE HURLEY/@译:断桥bian    网络性能问题是一个老生长谈的问题。网络是应用和数据的基础。所以一旦这一层出现问题,那么将会影响上层应用的体验。 造成网络性能问题的原因有...

    网络丢包的四大原因和修复方法

      MIKE HURLEY/@译:断桥bian

       网络性能问题是一个老生长谈的问题。网络是应用和数据的基础。所以一旦这一层出现问题,那么将会影响上层应用的体验。 造成网络性能问题的原因有很多种,但是在这篇文章中我们主要讨论丢包引起的网络性能问题。下面所说的引起丢包的四种原因是我们经常遇到的。

    网络链接阻塞

       数据在网络传输的过程中会经过很多设备和网路链接。 只要其中一个网路链接在数据传输过来之前已经满负载了,那么数据将会在这里阻塞一段时间,然后在经过网络线路传送(这也就是所谓的排队)。 如果说网络设备非常落后于这个网路链接的话,那么网路链接没有足够给新数据来等待的空间。所以它唯一能做的事情就是将信息丢掉。
       "数据被丢弃"可能会听起来很残酷,但是大多数应用程序都能在不影响用户体验的情况下,很好的处理这种问题。用户端的应用程序,一旦发现丢包情况的发生, 它就会相应地降低传输速率,或者重新传输数据。如果它不是一个实时应用,那么只要丢包不是持续发生,那么受的影响都比较小。
       一些应用程序在这方面处理的不好的话,那么丢包就会影响应用程序的用户体验。如果在你打电话的过程中发生丢包,由于它是一个实时性的对话,这时候没有时间 去重新发送。那么用户在丢包的时候,会发现通话断断续续,如果丢包严重的话,通话甚至可能会断掉,。另一个要低丢包率的重要程序是视频会议程序。如果两个用户端之间发生丢包,那么视频会 出现伪影,音频将会扭曲。

    解决方法

       我们可以通过以下两种方法来降低由网络链接阻塞引起的丢包的影响。

    • 增加阻塞链接的带宽
    • 使用Qos(流量优先级和资源保留控制机制)优先处理实时应用.尽管这种方法并不能缓解网络链接阻塞情况,但是它可以优先处理语音和视频来降低断线的可能性。

    (路由器/交换机/防火墙/等等)的设备性能

       如果带宽充足,但是如果你的路由器/交换机/防火墙不能处理流量,那么你仍然有面对丢包的情况. 让我们考虑一个场景,你刚将网络带宽从 1Gb 升级到 10Gb , 因为流量报告显示, 日高峰时期流量达到了顶点。升级之后, 你的图表显示你可以达到 1.5Gb , 但是你仍然遭受这网络性能问题。这个问题可能是应为设备能力无法处理流量, 你已经达到了你硬件所能提供的最大 的流量。
       当网络数据包传送到达网络设备,但是此时网络设备的CPU,或者内存满载了,并没有能力来处理其他的数据包。这导致设备不能处理的数据包都被丢弃。

    解决方法

       你必须更换吞吐量更大,性能更好的网络硬件,或者构建集群来提高吞吐量。

    网络设备上的软件问题(bug)

       我们可能都希望我们网络设备上的软件是完美的,但是我可以肯定的告诉你事实并不是如此。这些网络设备十分复杂.你遇到bug只是时间问题而已。
       当你部署的新功能的时候,这些bug可能会导致新功能无法工作,或者你在没发现网络性能问题之前的一段时间,你可能无法察觉这些bug的存在。

    解决方法

       你必须更新受软件问题影响的设备上的软件。

    硬件或网络缆线的毛病

       你的网络报告显示,你的网络链接并没有过载,硬件也没有违规使用。另外一个常见的导致丢包的问题可能是由物理组件的故障引起的。
       如果硬件故障,那么它通常会在设备终端上或者系统日志中输出错误信息。
       如果是网络链接错误,一般是网络接口出错。这可以在铜缆线和光纤上检测到。

    解决方法

       故障的硬件必须更换, 故障的网络链接必须修复。
       这些是网络丢包的常见原因。但是其他很多原因也会导致丢包。确定根源的最好的方法就是通过网络评估和彻底的故障排查。
       一个擅长于发现的各种网络的问题的伙伴可以帮助你制定补救策略, 让你免受糟糕的网络的困扰。

    展开全文
  • 网络丢包是网络中常见的故障之一,它会引起网速降低甚至造成网络中断,本文就在日常的网络管理工作中常见的几种丢包故障现象进行了分析和探讨并提出了处理方法。 所谓网络丢包是我们在使用ping命令(检测某个系统...
  • 网络丢包问题的原因及解决办法

    万次阅读 2019-09-03 10:37:35
    常见的测试丢包的命令 :ping 、mtr 、traceroute 常见的测试丢包的方法是通过使用PING命令进行测试 解析 :ping使用了ICMP回送请求与回送回答报文。ICMP回送请求报文是主机或路由器向一个特定的目的主机发出的...
  • 网络经常丢包原因

    千次阅读 2016-04-22 18:41:11
    像一些网络经常掉线、卡滞、慢等问题,几种因素有关 1、外网带宽不足 2、有人用BT、迅雷疯狂下载,把别的机器网速给占用了 3、有人用P2P终结者、网络执法官、聚生虫等软件限制别人的速度 4、有些电脑中了ARP病毒...
  • 所谓丢包,是指在网络数据的收发过程中...接下来,我就以最常用的反向代理服务器 Nginx 为例,带你一起看看,如何分析网络丢包 的问题。 执行下面的 hping3 命令,进一步验证 Nginx 是不是真的可 以正常访问了。注意.
  • 许多时候,我们可能都会碰到网络连接时断时续的故障现象,面对这种网络故障,不少网络管理员都会使用Ping命令对网络连通性进行测试,测试结果表明此时的网络传输线路数据丢包现象非常严重,那么究竟是什么因素导致了...
  • 在本文中我会总结一些论文相关论文中关于网络丢包的原因的论述. 网络中的丢包可以分为如下几个类型: 拥塞: 这个比较好理解, 就是交换机/路由器中多个端口向一个端口发送数据包, 最后导致数据包数量超过了这个端口...
  •  本文介绍了影响VoIP QoS时需考虑的时延、抖动、丢包率、带宽因素,NGN承载网安全性与可靠性的考虑,以及NGN承载网的各层面建设方案等内容。 1 引言  NGN是下一代电信网的发展趋势,虽然目前其体系架构、...
  • 许多时候,我们可能都会碰到网络连接时断时续的故障现象,面对这种网络故障,不少网络管理员都会使用Ping命令对网络连通性进行测试,测试结果表明此时的网络传输线路数据丢包现象非常严重,那么究竟是什么因素导致了...
  • 网络拥塞造成监控数据丢包的原因

    千次阅读 2018-09-04 16:47:40
    在网管员发现广域网线路时通时断,发生这种情况时,有可能是线路出现故障,也可能是用户方面的原因,也有网络拥堵造成的,下面分析下网络拥堵造成丢包的原因。 (监控) 网络拥塞造成丢包率上升的原因很多,主要...
  • 今天我来为大家讲解一下什么是服务器丢包率,以及服务器丢包率有哪些影响,好了,现在我们来概括一下丢包率是什么以及影响,服务器正常运行只要机房提供的宽带是稳定的,而还会持续不断的丢包原因只有一个,那就是超...
  • 数据丢包引起的。那么,我们该如何准确、有效地解决这些故障现象呢?为此,本文从实战角度出发,为大家贡献一则网络中断故障的详细排除过程,希望大家能从 中获得启发! 故障回放 笔者所在单位局域网大约包含100台...
  • ›时延:时延对游戏的影响主要表现在执行操作和得到反馈的时间差。大部分主流网络游戏都是C/S架构...›丢包丢包对游戏的影响表现在突发性的卡顿、人物倒退甚至掉线重连,严重影响游戏体验。丢包在一定程度上可以归...
  • 服务器网络故障处理——ping丢包或不通时链路测试说明前言当客户端访问目标服务器出现 ping 丢包或 ping 不通时,可以通过 tracert 或 mtr 等工具进行链路测试来判断问题来源。本文先介绍了进行链路测试的相关工具,...
  • 尤其是海外的服务器,出现这样不可控制的因素有:网络故障(机房网络、中转网络以及本地网络)只要其中一个出现故障就会导致香港服务器丢包现象出现。 服务器严重丢包,正常的服务器丢包率为0%,若丢包率高于1%则会...
  • 丢包率 利用率 一、往返时间(RTT) 1.超时时间: 概念:例如在TCP协议中,当一台主机向连接发送一个报文段(数据包),它会开启一个计时器,如果计时器在主机接收到该报文段数据的确认之前超时,那么这台主机...
  • 直播丢包解决方案

    2020-11-29 22:37:24
    直播丢包问题是流媒体中一直关注的重要问题,如何解决直播的丢包问题呢?先从直播流程入手: 一般直播流程大体上:采集→前处理→编码→推流→分发→拉流→解码→播放。 引起直播的丢包延迟的主要原因有两种: 1...
  • ping丢包故障处理方法

    千次阅读 2018-09-12 12:15:08
    在使用Ping命令,出现Ping丢包的现象时,第一步需要确定Ping丢包网络位置,其次是确定Ping丢包的故障原因,然后依据定位的故障原因再进行解决。确认Ping丢包网络位置时一般采用逐段Ping的方法,可以将Ping...
  • 现在有很多硬件平台理论上支持千兆以太网接口,但...二、影响吞吐量和丢包率的因素 1. 网卡DMA缓冲区大小 这个缓冲区决定tx ring buffer和rx ring buffer的大小,如果ring buffer太小,那么网卡缓存数据包的能力...
  • 丢包是什么意思

    千次阅读 2019-07-31 10:01:34
    丢包,顾名思义,在通信...网络中数据的传输是以发送和接收数据包的形式传输的,理想状态下是发送了多少数据包就能接收到多少数据包,但是由于信号衰减、网络质量等等诸多因素影响下,并不会出现理想状态的结果,...
  • 收端程序:主函数对应开启4个收线程,每个线程收取对应端口的数据,收到数据包即时封装处理。 其他说明: 本地收发。如果不限制发包速率将会非常快 基于UDP。使用recvfrom()函数收 recvfrom()接收后立即将...
  • 误码率与丢包

    千次阅读 2013-02-25 10:13:02
    误码率与丢包率 今天就个人对误码率和丢包率的理解跟大家探讨一下,还是举个例子来说明比较直观:   假设如图所示为一段网络上传送的数据(当然必然是二进制了),长度为 34 比特。图中第一行是为方便说明...
  • linux 系统 UDP 丢包问题分析思路

    千次阅读 2018-01-18 10:54:18
    https://www.tuicool.com/articles/7ni2yyr最近工作中遇到某个服务器应用程序 UDP 丢包,在排查过程中查阅了很多资料,总结出来这篇文章,供更多人参考。在开始之前,我们先用一张图解释 linux 系统接收网络报文的...
  • UDP主要丢包原因及具体问题分析

    万次阅读 2015-08-28 00:20:44
    UDP主要丢包原因及具体问题分析   一、主要丢包原因   1、接收端处理时间过长导致丢包:调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来的包可能...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,446
精华内容 6,978
关键字:

影响网络丢包的因素