网络编程之网络丢包故障如何定位?如何解决?( 七 )

  • 看一下是不是应用程序设置限制, 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 stamp825313 packets rejects in established connections because of timestamp通过sysctl查看是否启用了tcp_tw_recycle及tcp_timestamp:
    $ sysctl net.ipv4.tcp_tw_recyclenet.ipv4.tcp_tw_recycle = 1 $ sysctl net.ipv4.tcp_timestampsnet.ipv4.tcp_timestamps = 11. 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_memcat /proc/sys/net/ipv4/tcp_rmemcat /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 -pTCP超时丢包
    查看:
    抓包分析一下网络RTT:
    网络编程之网络丢包故障如何定位?如何解决?

    文章插图
     
    用其他工具测试一下当前端到端网络质量(hping等);
    # hping -S 9.199.10.104 -AHPING 9.199.10.104 (bond1 9.199.10.104): SA set, 40 headers + 0 data byteslen=46 ip=9.199.10.104 ttl=53 DF id=47617 sport=0 flags=R seq=0 win=0 rtt=38.3 mslen=46 ip=9.199.10.104 ttl=53 DF id=47658 sport=0 flags=R seq=1 win=0 rtt=38.3 mslen=46 ip=9.199.10.104 ttl=53 DF id=47739 sport=0 flags=R seq=2 win=0 rtt=30.4 mslen=46 ip=9.199.10.104 ttl=53 DF id=47842 sport=0 flags=R seq=3 win=0 rtt=30.4 mslen=46 ip=9.199.10.104 ttl=53 DF id=48485 sport=0 flags=R seq=4 win=0 rtt=38.7 mslen=46 ip=9.199.10.104 ttl=53 DF id=49274 sport=0 flags=R seq=5 win=0 rtt=34.1 mslen=46 ip=9.199.10.104 ttl=53 DF id=49491 sport=0 flags=R seq=6 win=0 rtt=30.3 ms


    推荐阅读