当前位置:首页 > 运维 > 正文内容

linux中nf_conntrack table full dropping packet问题处理

phpmianshi5年前 (2016-04-16)运维227

概述:


在日常的服务器运维过程中,发现某段时间 /var/log/messages日志报错
nf_conntrack:table full,drop packet

简介:

nf_conntrack是内核模块中的连接追踪模块。与iptables有关。用于跟踪一个连接状态。连接跟踪状态可以供其他模块使用,例如state等,可通过以下查看

[root@VM_0_11_centos vhost]#          lsmod |egrep conntrack
nf_conntrack_ipv4      15053  0
nf_defrag_ipv4         12729  1 nf_conntrack_ipv4
nf_conntrack          133053  1 nf_conntrack_ipv4
libcrc32c              12644  2 sctp,nf_conntrac

# 查看nf_conntrack表最大连接数
[root@VM_0_11_centos vhost]# cat /proc/sys/net/netfilter/nf_conntrack_max
6553500
# 查看nf_conntrack表当前连接数
[root@VM_0_11_centos vhost]# cat /proc/sys/net/netfilter/nf_conntrack_count
114

查出目前 nf_conntrack 的排名:
[root@VM_0_11_centos vhost]# cat /proc/net/nf_conntrack |awk '{print $11}' |cut -d '=' -f 2 | sort |uniq -c | sort -nr | head -n 10
     55 169.254.0.4
     31 172.16.0.11
      1 169.254.0.55
      1 169.254.0.15
      1 0

当有大量的网站访问时,若iptables记录连接跟踪状态,就可能导出现“nf_conntrack:table full”,从而导致一系列问题。

像php-fpm这种提供web短连接服务的项目,server端主动断开连接成功就会有个2MLS的time_wait,这些连接也都被track,该conntrack也会占用2分钟的时间。

这都不用并发太高的环境,比如每秒并发个100,2MLS的时间2分钟得生成2x60x100=12000,生成1万多的time_wait记录。这里就是个短连接不断积累的过程,不断地server主动断开,不断地timewait,这些都会被conntrack跟踪记录。所以一般默认的nf_conntrack_max=65535,很快就被塞满了。一旦塞满了就会随机的drop包。在外面看来就是丢包情况非常厉害。


解决方案:


1.优化参数

nf_conntrack_max决定连接跟踪表的大小,默认值是65535,理论最大值官方有个计算公式

CONNTRACK_MAX = RAMSIZE (in bytes) / 16384 / (ARCH / 32)
以16G的64位操作系统为例,CONNTRACK_MAX = 16*1024*1024*1024/16384/2 = 524288

nf_conntrack_buckets决定存储conntrack条目的哈希表大小,其哈希表大小通常为总表的1/8,最大为1/2。默认值是nf_conntrack_max的1/4  

CONNTRACK_BUCKETS = CONNTRACK_MAX / 4
同样64G的64位操作系统,哈希最佳范围是 65536 ~ 262144 。
运行状态中通过 sysctl net.netfilter.nf_conntrack_buckets 进行查看

旧版本修改: echo 262144 >  /sys/module/nf_conntrack/parameters/hashsize 进行设置

4.9内核下能直接修改 /proc/sys/net/netfilter/nf_conntrack_buckets


nf_conntrack_tcp_timeout_established决定ESTABLISHED状态连接的超时时间,默认值是5天,可以缩短到1小时,即3600。

还有些相关的系统参数`sysctl -a | grep nf_conntrack`可以调优(/etc/sysctl.conf ): 

vim /etc/sysctl.conf
#加大 ip_conntrack_max 值
net.nf_conntrack_max = 524288

net.netfilter.nf_conntrack_max = 524288

net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_established = 3600

增加完以上内容后,通过sysctl -p 使配置生效 。不过该方法缺点:一是重启iptables后,ip_conntrack_max值又会变成65535默认值,需要重新sysctl -p


2.移除模块

modprobe -r xt_NOTRACK nf_conntrack_netbios_ns nf_conntrack_ipv4 xt_state
modprobe -r nf_conntrack

执行完查看/proc/net/ 下面如果没用了 nf_conntrack ,就证明模块移除成功了

注意: 此方法会将state模块也一块儿移除掉,如果我们的iptables应用nat会用到state模块,卸载后导致iptables某些功能无法使用。


3.使用raw表,跳过跟踪记录。

首先先认识下什么是raw表?做什么用的?

iptables有5个链:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING,4个表:filter,nat,mangle,raw 。

4个表的优先级由高到低的顺序为:raw–>mangle–>nat–>filter

举例来说:如果PRROUTING链上,即有mangle表,也有nat表,那么先由mangle处理,然后由nat表处理 。

RAW表只使用在PREROUTING链和OUTPUT链上,因为优先级最高,从而可以对收到的数据包在连接跟踪前进行处理。一但用户使用了RAW表,在某个链上,RAW表处理完后,将跳过NAT表和 ip_conntrack处理,即不再做地址转换和数据包的链接跟踪处理了。
RAW表可以应用在那些不需要做nat的情况下,以提高性能。如大量访问的web服务器,可以让80端口不再让iptables做数据包的链接跟踪处理,以提高用户的访问速度 。

使用方法:
(1)改/etc/sysconfig/iptables 文件中的-A INPUT -m state –state RELATED,ESTABLISHED, UNTRACKED -j ACCEPT 行。增加”UNTRACKED”,保存并restart iptables
注意: 必须更改此步,增加”UNTRACKED“,否则执行后面的语句会造成相应的端口不能访问。我使用该方法时就因为没有执行第一步的操作,造成web访问不能使用。
(2)增加以下语句

# 针对进入本机的包
/sbin/iptables -t raw -A PREROUTING -p tcp -m multiport --dports 80 -j NOTRACK
# 针对从本机出去的包
/sbin/iptables -t raw -A OUTPUT  -p tcp -m multiport --sports 80 -j NOTRACK
/sbin/iptables -t raw -A PREROUTING -i lo -j NOTRACK
/sbin/iptables -t raw -A OUTPUT  -o lo -j NOTRACK

注意: 一定将进入和出去的包都设置规则。这样的好处是治本,把不需要track的iptables直接notrack,那自然就不会去占hashtable空间了,更不会报错了。


版权声明:本文由PHP面试资料网发布,如需转载请注明出处。
分享给朋友:

相关文章

记一次laravel项目因opcache导致的include过慢问题

问题表现 php-fpm-slow.log 大量如下日志:script_filename = /data/nginx/webroot/app-20200611-160330-feb...

Nginx面试中最常见的18道题

1、请解释一下什么是Nginx?Nginx---Ngine X,是一款免费的、自由的、开源的、高性能HTTP服务器和反向代理服务器;也是一个IMAP、POP3、SMTP代理服务器;Nginx以其高性能...

linux中查看系统活动情况报告sar命令详解

有很多工具可以看网络流量,但我最喜欢sar。sar(System Activity Reporter系统活动情况报告)是目前 Linux 上最为全面的系统性能分析工具之一,可以从多...

守护进程详解及其代码实现

1、概念理解:守护进程(Daemon)是运行在后台的一种特殊进程,也称为精灵进程。是生存期较长的一种进程,常常在系统自举时启动,仅在系统关闭时终止。没有控制终端,仅仅在后台运行,Linux有很多守护进...

jmeter压测实战

jmeter压测实战

下载安装下载JDK  : https://download.oracle.com/otn-pub/java/jdk/15.0.2+7/0d1cfde4252546c6931946de8db4...






TCP(Transmission Control Protocol) 传输控制协议

三次握手

TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接:

位码即tcp标志位,有6种标示:

SYN(synchronous建立联机) 同步报文段

ACK(acknowledgement 确认)

PSH(push传送)

FIN(finish结束) 结束报文段

RST(reset重置) 复位报文段

URG(urgent紧急) 紧急指针

Sequence number(顺序号码)

Acknowledge number(确认号码)

客户端TCP状态迁移:

CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED

服务器TCP状态迁移:

CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED


各个状态的意义如下: 

LISTEN - 侦听来自远方TCP端口的连接请求; 

SYN-SENT -在发送连接请求后等待匹配的连接请求; 

SYN-RECEIVED - 在收到和发送一个连接请求后等待对连接请求的确认; 

ESTABLISHED- 代表一个打开的连接,数据可以传送给用户; 

FIN-WAIT-1 - 等待远程TCP的连接中断请求,或先前的连接中断请求的确认;

FIN-WAIT-2 - 从远程TCP等待连接中断请求; 

CLOSE-WAIT - 等待从本地用户发来的连接中断请求; 

CLOSING -等待远程TCP对连接中断的确认; 

LAST-ACK - 等待原来发向远程TCP的连接中断请求的确认; 

TIME-WAIT -等待足够的时间以确保远程TCP接收到连接中断请求的确认; 

CLOSED - 没有任何连接状态;


TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接,如图1所示。

(1)第一次握手:建立连接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_SEND状态,等待服务器B确认。

(2)第二次握手:服务器B收到SYN包,必须确认客户A的SYN(ACK=j+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器B进入SYN_RECV状态。

(3)第三次握手:客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK(ACK=k+1),此包发送完毕,客户端A和服务器B进入ESTABLISHED状态,完成三次握手。

完成三次握手,客户端与服务器开始传送数据。

确认号:其数值等于发送方的发送序号 +1(即接收方期望接收的下一个序列号)。

图1 TCP三次握手建立连接  


TCP协议中的三次握手和四次挥手

理解:窗口和滑动窗口TCP的流量控制TCP使用窗口机制进行流量控制什么是窗口?连接建立时,各端分配一块缓冲区用来存储接收的数据,并将缓冲区的尺寸发送给另一端接收方发送的确认信息中包含了自己剩余的缓冲区...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。