当前位置:首页>微思动态 > >详情
全国热线电话 400-881-4699

在线留言

故障排除案例——系统丢包无法建立连接

发布作者:微思网络   发布时间:2023-06-13   浏览量:0


现象

访问量较高的服务器出现严重的丢包和无法建立连接的情况,而所有服务均显示正常,但还会偶尔出现断流和丢包现象。


问题排查

在bash 中执行 dmesg命令,发现出现大量的“nfconntracktablefulldropping packet"条目

Bash:
[root@localhost~]# dmesg
... output ommited...
[3470.830917] nfconntrack:nfconntrack table full,dropping packet
[3508.652803] nfconntrack:nfconntrack table full,dropping packet
[3517.666339] nf_conntrack: nfconntrack: table full,dropping packet
[root@localhost~]#

使用journalctl 命令一样也可以看到该信息

Bash:
[root@localhost~]#iournalctl-r
Feb 21 03:56:01 localhostlocaldomain kernel:nf conntrack:nf conntrack: table full, dropping packet
Feb 21 03:55:51 localhostlocaldomain kernel:nfconntrack:nf conntrack: table full, dropping packet
Feb 21 03:55:51 localhost.localdomain kernel:nf conntrack:nf conntrack table full, dropping packet

... output ommited...

原因

这是由于当前系统连接数量(默认为65536)超出最大限制所导致,该值由内核参数netnetfilter.nf_conntrack_max定义

使用sysctl 命令可以查看该值

Bash:
[root@localhost~]# sysctl -a|grep nf_conntrack max
net.netfilter.nfconntrack max=65536
net.nfconntrack max=65536

意味着默认情况下,最多维持65536个连接数,一旦连接数超出该值,系统就会拒绝后续的连接,直到前面的连接被系统释放后才能继续处理新连接。


查看系统当前连接数

要查看当前系统维持了多少个连接数,可以真看/proc/sys/net/netfilter/nf_conntrack_count文件

Bash:
[root@localhost~]#cat/proc/sys/net/netfilter/nf_conntrack_count
10

要查看这10个连接的详细信息,可以查看/proc/net/nf_conntrack文件

Bash:
[root@localhost~]#cat/proc/net/nfconntrack
ipv42icmp
129 src=192.168.157.128 dst=1.1.11 type=8 code=0 id=24021 src=1.1.1.1
dst=192.168.157.128 type=0 code=0 id=24021 mark=0 secctx=system uobiect runlabeled ts0 zone=0 use=2
ipv4
2 icmp
129 src=192.168.157.128 dst=1.1.11type=8 code=0 id=24205 src=1.1.1.1
dst=192.168.157.128 tvpe=0 code=0 id=24205 mark=0 secctx=svstem uobiect runlabeled t;s0 zone=0 use=2
ipv42icmp
129 src=192.168.157.128 dst=1.1.11 type=8 code=0 id=24008 src=1.1.1.1
dst=192.168.157.128 type=0 code=0 id=24008 mark=0 secctx=system uobjectrunlabeled ts zone=0 use=2
... output ommited ...

文件的内容在终端屏幕上显示会感觉杂乱无章,需要把字体调小才可以完整的看到一整行,但无所谓了whocare,毕竟这个文件也不是为了给用户看的

当然也可以直接查看这个文件,并通过管道符查看已经建立的连接数,效果与/proc/sys/net/netfilter/nf conntrack count一样

Bash:
[root@localhost~]#cat/proc/net/nfconntrackwc-1
10

修改系统默认最大连接数

1.使用sysct1 命令可以直接修改(*仅演示这种方法,该方法仅临时生效)

2.通过修改/etc/sysctlconf文件后执行sysctl-p命令使配置文件立即生效(永久生效)

首先找到参数的完整名字,使用sysctl-a 配合grep 过滤

Bash:
[root@localhost~]# sysctl -a|grep nf_conntrack_max
net.netfilter.nf_conntrack max=65536#RHEL 6以上用这个
net.nf conntrack max=65536
# RHEL 5 用这个
[root@localhost~]#

根据需求自行设置该值,注意:通常需要根据服务器自身内存大小来设置(每个连接预计占用250~500Byte内存)。这里将该值设置为2^20,使用sysctl-w命令可立即生效

Bash:
[root@localhost~]# sysctl -wnet.netfilternfconntrackmax=1048576
net.netfilter.nf conntrack max=1048576
[root@localhost~]#
实验:修改最大连接数,观察满了后的效果

步骤如下:

1查看当前系统连接数

2.修改系统最大连接数为当前连接数

3.使用ping命令验证并观察效果

1.查看当前系统连接数

查看/proc/sys/net/netfilter/nf_conntrack_count文件

Bash:
[root@localhost~]# cat/proc/sys/net/netfilter/nf_conntrackcount

查看这个连接的详细信息,查看/proc/net/nf_conntrack文件

Bash:
[root@localhost~]#cat/proc/net/nf_conntrack
ipv4
2 tcp
6 299 ESTABUISHED src=192.168.157.1 dst=192.168157128 sport=12895 dport=22
src=192.168.157.128 dst=192.168.157.1 sport=22 dport=12895[ASSURED] mark=0 secctx=system u:obiect r:unlabeled t;s0 zone=0 use=2

可以看到当前的连接就是自己连接到Bash的ssh


2.修改系统最大连接数为当前连接数

使用sysct1命令修改内核参数netnetfilter.nf_conntrack max的值为1

Bash:
[root@localhost~]# sysctl -wnet.netfilternfconntrackmax=1
net.netfilter.nf conntrack max=1

3.使用 ping 命令验证并观察效果

使用ping命令检测wwwbaidu.com的连通性

Bash:
[root@localhost~]#ping www.baidu.com
ping:www.baidu.com: Name or service not known

使用ping命令检测wwwbaidu.com的连通性

Bash:
[root@localhost~]#cat/etc/resolv.conf
# Generated by NetworkManager
search localdomain
nameserver 192168.157.2

使用ping命令检测DNS的地址连通性

Bash:
[root@localhost~]#ping192168157.2
PING 192168.157.2(192168157256(84) bytes of data.
ping:sendmsg:Operation not permitted
ping:sendmsg:Operation notpermitted
ping:sendmsg:Operation notpermitted
^C
---192168.157.2 ping statistics--
3 packets transmitted, 0 received, 100% packet loss,time 2078ms
[root@localhost~]#

可以看到提示信息为“Operation not permitted,意味着当前能够建立的最大连接(1个,被终端本身占用了)已经满了,所以就拒绝了后续所有连接

现在重新将netnetfilter.nfconntrackmax的值改为65536默认值(执行sysct-wnetnefilternf conntrack max=65536)

然后使用 for 命令创建5000个连接,并观察内存使用量

Bash:
[root@localhost ~]# for i in {1..5000}; do ping 1.1.1.1 &>/dev/null & donecn
... output ommited...
[4998] 6887
[4999] 6888
[5000] 6889
[root@localhost~]#
[root@localhost~]# free -h
       total      used     free    shared    buff/cache    available
Mem:    3.6Gi      3.1Gi    226Mi   8.0Mi     257Mi         243Mi
Swap:   2.0Gi      0B       2.0Gi
[root@localhost~]#

可以看到5000个连接几乎占满了3.6GB内存。排除系统原先内存占用的话,粗略计算大概一个连接需要500 Byte的内存


实验总结:该值控制着系统的连入/连出数量,只要用户不要手动改小,默认65536在非极端情况下非常够用,因为维持连接数是需要消耗内存的,内存不够即使设置再大也无济于事


增加连接数大小后的必要调优手段

如果手动增加了最大连接数,如果相比之前的值大了4倍(默认是65536,如果新值超过262144),有必要修改存储conntack条哈表大小以提高效率

conntrack哈希表大小信息保存在/sys/module/nf_conntrack/parameters/hashsize文件中

Bash:
[root@localhost~#cat/sys/module/nfconntrack/parameters/hashsize
16384

单位是Byte(字节),也就是16KB

哈希值大小最好遵循以下规则:
  • 最好是2的次幂*注:conntrackmax最好设置的时候也遵循这个规则,conntrackmax默认65536=2^16

  • 经验法则:hashsize=conntrack max/4


重要的

默认情况下,当用户仅设置了 hashsize 后,系统会自动修改nf_conntrack max的值为hashsize x8

但当仅设置了 nf_conntrack_max 的值后,并不会自动修改 hashsize

所以这就是为什么这是"必要的调优手段"的原因


修改nfconntrack的hashsize


首先永久修改并立即生效nf_conntrack_max的值为1048576(2^10)

Bash:
[root@localhost~]# echo"net.netfilternfconntrack max=1048576”>>/etc/sysctl.conf
[root@localhost~]# sysctl -p
net.netfilter.nf_conntrack max=1048576

接着修改nfconntrack的内核模块参数,在/etc/modprobed目录下创建一个同名的内核模块配置文件:nfconntrack.conf写入以下内容

/etc/modprobe.d/nf conntrack.conf:
options nf conntrack expect hashsize=262144 hashsize=262144

此处的262144 是通过nf_conntrack max(1048576)÷4得来

最后直接重启系统即可生效


Bash:
[root@localhost~]#reboot
#如果不想重启,需要立即生效
[root@localhost~]# echo"262144">/sys/module/nfconntrack/parameters/hashsize

故障排查 

可以检查cpu上丢弃的数据包,通过查看/proc/net/stat/nfconntrack文件的early drop 列

Bash:
[root@localhost~]#cat/proc/net/stat/nfconntrack
entries  ... ...insert insert_failed drop early_drop icmp_error expect_new expect_create expect_delete search_restart
00000005 ... ...00000000 00000000 00000000 00004088 00000000 00000000 00000000 00000000 00000000 00000000
00000005 ... ...00000000 00000000 00000000 000041f8 00000000 00000000 00000000 00000000 00000000 00000000
00000005 ... ...00000000 00000000 00000000 000043e6 00000001 00000000 00000000 00000000 00000000 00000000
00000005 ... ...00000000 00000000 00000000 000042e9 00000001 00000000 00000000 00000000 00000000 00000000
00000005 ... ...00000000 00000000 00000000 000040dd 00000000 00000000 00000000 00000000 00000000 00000000
00000005 ... ...00000000 00000000 00000000 000043e4 00000000 00000000 00000000 00000000 00000000 00000000 
00000005 ... ...00000000 00000000 00000000 0000415f 00000000 00000000 00000000 00000000 00000000 00000000
00000005 ... ...00000000 00000060 00000000 0000423a 00000000 00000000 00000000 00000000 00000000 00000000
00000005 ... ...00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000005 ... ...00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000005 ... ...00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  
... output ommited..

最上面一行是最新的数据,以16进制表示。 

第一行4088=16520个 

第二行41f8=16888个 

第三行43e6=17382个


需要原文PDF档的童鞋记得加客服微信备注“案例”即可获得原文件

扫码加微信

图片




返回顶部