[转]Linux内核调优之处理大量TIME_WAIT

Linux下高并发的nginx,apache,lvs,haproxy,squid等服务器生产环境下,TCP的TIME_WAIT套接字数量经常达到2-3W,此时服务器很容易被拖死或者严重影响业务服务。

如果解决这个问题呢?

可以通过修改Linux的内核参数,减少和控制服务器的TIME_WAIT的数量

  • 获取TCP TIME_WAIT状态数量

?(生产服务器某个业务LVS负载均衡上连接状态数量)

[oldboy@LVS-1-1 ~]$ netstat -n |awk ‘/^tcp/ {++oldboy[$NF]} END {for(a in oldboy) print a, oldboy[a]}'

TIME_WAIT 9137

CLOSE_WAIT 207

FIN_WAIT1 547

ESTABLISHED 597

FIN_WAIT2 74

SYN_RECV 70

CLOSING 55

LAST_ACK 8

 

[root@lvs_nginx~]#netstat -n |awk ‘/^tcp/ {++oldboy[$NF]} END {for(a in oldboy) print a, oldboy[a]}'

TIME_WAIT 422

CLOSE_WAIT 590

FIN_WAIT1 56

FIN_WAIT2 28

ESTABLISHED 1731

  • tcp连接状态的描述说明(netstat输出)

执行netstat -n查看输出结果共6

[root@OLDBOY ~]# netstat -n 

Active Internet connections (w/o servers)

Proto Recv-Q Send-Q Local AddressForeign AddressState

tcp00 10.0.0.183:5058410.0.0.181:22ESTABLISHED 

通过man netstat查看netstat输出结果信息

[root@oldboy ~]# man netstat 

OUTPUT

Active Internet connections (TCP, UDP, raw)

Proto

The protocol (tcp, udp, raw) used by the socket.

第一列为socket使用的协议。

Recv-Q

The count of bytes not copied by the user program connected to this socket.

第二列为接到的但是还没处理的字节数。

Send-Q

The count of bytes not acknowledged by the remote host.

第三列为已经发送的但是没有被远程主机确认收到的字节数。

Local Address

Address and port number of the local end of the socket.Unless the –numeric(-n)

optionisspecified,thesocketaddress is resolved to its canonical host name

(FQDN), and the port number is translated into the corresponding service name.

第四列为 本地的地址及端口。

Foreign Address

Address and port number of the remote endofthesocket.Analogousto"Local Address."

第五列为外部的地址及端口。

State

Thestateofthesocket.Sincethere are no states in raw mode and usually no

states used in UDP, this column may be left blank. Normally this can be one of sev-

eral values:

第六列为socket的状态,通常仅仅有tcp的状态,状态值可能有ESTABLISHED,SYN_SENT,SYN_RECV FIN_WAIT1,FIN_WAIT2,TIME_WAIT等,详见下文。其中,最重要的是第六列。

第六列State的状态信息

如果我们执行man netstat可以找到如下的帮助信息

State

Thestateofthesocket.Sincethere are no states in raw mode and usually no

states used in UDP, this column may be left blank. Normally this can be one of sev-

eral values:

第六列为socket的状态,通常仅仅有tcp的状态,状态值可能有ESTABLISHED,SYN_SENT,SYN_RECV FIN_WAIT1,FIN_WAIT2,TIME_WAIT等,详见下文。其中,最重要的是第六列。

ESTABLISHED

The socket has an established connection.

socket已经建立连接,表示处于连接的状态,一般认为有一个ESTABLISHED认为是一个服务的并发连接。这个连接状态在生产场景很重要,要重点关注。

SYN_SENT

The socket is actively attempting to establish a connection. 

socket正在积极尝试建立一个连接,即处于发送后连接前的一个等待但未匹配进入连接的状态。

SYN_RECV

A connection request has been received from the network.

已经从网络上收到一个连接请求。

FIN_WAIT1

The socket is closed, and the connection is shutting down. 

socket已关闭,连接正在或正要关闭。

FIN_WAIT2

Connectionisclosed,andthesocket is waiting for a shutdown from the remote end.

连接已关闭,并且socket正在等待远端结束。

TIME_WAIT

The socket is waiting after close to handle packets still in the network.

socket正在等待关闭处理仍在网络上的数据包,这个连接状态在生产场景很重要,要重点关注。

CLOSED The socket is not being used.| socket不在被占用了。

CLOSE_WAIT

The remote end has shutdown, waiting for the socket to close.

远端已经结束,等待socket关闭。

LAST_ACK

The remote end has shut down, and the socket is closed. Waiting for acknowl-edgement.|

远端已经结束,并且socket也已关闭,等待acknowl-edgement。

LISTEN Thesocketislisteningforincoming connections.Such sockets are not

included in the output unless you specify the –listening (-l) or –all (-a)

option.

socket正在监听连接请求。

CLOSING

Both sockets are shut down but we still don’t have all our data sent.

sockets关闭,但是我们仍旧没有发送数据。

UNKNOWN

The state of the socket is unknown

未知的状态。

 

高并发linux生产服务器内核参数优化案例

说明:本优化适合apache,nginx,squid多种等web应用,特殊的业务也可能需要略作调整。

所谓内核优化,主要是在Linux系统中针对业务服务应用而进行的系统内核参数优化,优化并无特殊的标准,下面以常见生产环境linux的内核优化为例讲解,仅供大家参考:

net.ipv4.tcp_fin_timeout = 2

#表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间

net.ipv4.tcp_tw_reuse = 1

#表示开启重用。允许TIME_WAIT sockets重新用于新的TCP连接,默认0,表示关闭

net.ipv4.tcp_tw_recycle = 1

#表示开启TCP连接中的TIME_WAIT socket的快速回收,默认为0,表示关闭

net.ipv4.tcp_syncookies = 1

#开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量的SYN攻击

net.ipv4.tcp_keepalive_time = 600

#表示当keepalive起作用的时候,TCP发送keepalive消息的频度,默认是2H,单位是秒

net.ipv4.ip_local_port_range = 4000 65000

#表示用于向外连接的端口范围,默认是32768到61000

net.ipv4.tcp_max_syn_backlog = 16384

#表示SYN队列的长度,默认是1024,加大队列的长度可以容纳更多的等待连接的网络连接数

net.ipv4.tcp_max_tw_buckets = 36000

#保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字会被立即清除并打印警告信息

默认是18000。对于web服务来说可以低一点,如:5k-30k;lvs,squid可以大一些

net.ipv4.route.gc_timeout = 100

net.ipv4.tcp_syn_retries = 1

net.ipv4.tcp_synack_retries = 1

net.core.somaxconn = 16384

net.core.netdev_max_backlog = 16384

net.ipv4.tcp_max_orphans = 16384

#以下参数是对iptables防火墙的优化,防火墙不开会提示,可以忽略不理。

net.ipv4.ip_conntrack_max = 25000000

net.ipv4.netfilter.ip_conntrack_max=25000000

net.ipv4.netfilter.ip_conntrack_tcp_timeout_established=180

net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait=120

net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait=60

net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait=120

将上面的内核参数值加入/etc/sysctl.conf文件中,然后执行如下命令使之生效:sysctl -p 

 

 

 

 

 

 

 

 

 

 

 

[转]Linux内核调优之处理大量TIME_WAIT
Scroll to top