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


解决方案:
根据实际网络环境将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 = 1200net.netfilter.nf_conntrack_udp_timeout_stream = 180net.netfilter.nf_conntrack_icmp_timeout = 30ct创建冲突失导致丢包查看:当前连接跟踪统计: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_LOG11sysctl -w net.netfilter.nf_log.2=ipt_LOG然后发包后在查看syslog;
解决方案:根据实际抓包分析情况判断是不是此机制导致的丢包,可以试着关闭试一下;
分片重组丢包情况总结:超时
查看:
netstat -s|grep timeout601 fragments dropped after timeout解决方法:调整超时时间
net.ipv4.ipfrag_time = 30sysctl -w net.ipv4.ipfrag_time=60frag_high_thresh, 分片的内存超过一定阈值会导致系统安全检查丢包
查看:
netstat -s|grep reassembles8094 packet reassembles failed解决方案:调整大小
net.ipv4.ipfrag_high_thresh net.ipv4.ipfrag_low_thresh分片安全距检查离丢包
查看:
netstat -s|grep reassembles8094 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 reassembles8094 packet reassembles faileddropwatch查看丢包位置 :
网络编程之网络丢包故障如何定位?如何解决?

文章插图
 
解决方案:
a.增大系统网络内存:
net.core.rmem_default net.core.rmem_max net.core.wmem_defaultb.系统回收内存:
紧急情况下,可以用 /proc/sys/vm/drop_caches, 去释放一下虚拟内存;
To free pagecache:# echo 1 > /proc/sys/vm/drop_cachesTo free dentries and inodes:# echo 2 > /proc/sys/vm/drop_cachesTo free pagecache, dentries and inodes:echo 3 > /proc/sys/vm/drop_caches


推荐阅读