当前位置: 移动技术网 > 网络运营>服务器>Linux > 探讨如何减少Linux服务器TIME_WAIT过多的问题

探讨如何减少Linux服务器TIME_WAIT过多的问题

2019年05月03日  | 移动技术网网络运营  | 我要评论

time_wait状态的意义:
客户端与服务器端建立tcp/ip连接后关闭socket后,服务器端连接的端口状态为time_wait
是不是所有执行主动关闭的socket都会进入time_wait状态呢?
有没有什么情况使主动关闭的socket直接进入closed状态呢?
主动关闭的一方在发送最后一个 ack 后就会进入 time_wait 状态 停留2msl(max segment lifetime)时间,这个是tcp/ip必不可少的,也就是“解决”不了的。
也就是tcp/ip设计者本来是这么设计的。

主要有两个原因
1。防止上一次连接中的包,迷路后重新出现,影响新连接(经过2msl,上一次连接中所有的重复包都会消失)
2。可靠的关闭tcp连接
在主动关闭方发送的最后一个 ack(fin) ,有可能丢失,这时被动方会重新发fin, 如果这时主动方处于 closed 状态 ,就会响应 rst 而不是 ack。所以主动方要处于 time_wait 状态,而不能是 closed 。
time_wait 并不会占用很大资源的,除非受到攻击。
在squid服务器中可输入如下命令:
#netstat -n | awk '/^tcp/ {++s[$nf]} end {for(a in s) print a, s[a]}'
last_ack 14
syn_recv 348
established 70
fin_wait1 229
fin_wait2 30
closing 33
time_wait 18122
状态:描述
closed:无连接是活动的或正在进行
listen:服务器在等待进入呼叫
syn_recv:一个连接请求已经到达,等待确认
syn_sent:应用已经开始,打开一个连接
established:正常数据传输状态
fin_wait1:应用说它已经完成
fin_wait2:另一边已同意释放
itmed_wait:等待所有分组死掉
closing:两边同时尝试关闭
time_wait:另一边已初始化一个释放
last_ack:等待所有分组死掉
也就是说,这条命令可以把当前linux服务器的网络连接状态分类汇总。
下面解释一下为啥要这样写:
一个简单的管道符连接了netstat和awk命令。
先来看看netstat:
netstat -n
active internet connections (w/o servers)
proto recv-q send-q local address foreign address state
tcp 0 0 123.123.123.123:80 234.234.234.234:12345 time_wait
你实际执行这条命令的时候,可能会得到成千上万条类似上面的记录,不过我们就拿其中的一条就足够了。
再来看看awk:
/^tcp/
滤出tcp开头的记录,屏蔽udp, socket等无关记录。
state[]
相当于定义了一个名叫state的数组
nf
表示记录的字段数,如上所示的记录,nf等于6
$nf
表示某个字段的值,如上所示的记录,$nf也就是$6,表示第6个字段的值,也就是time_wait
state[$nf]
表示数组元素的值,如上所示的记录,就是state[time_wait]状态的连接数
++state[$nf]
表示把某个数加一,如上所示的记录,就是把state[time_wait]状态的连接数加一
end
表示在最后阶段要执行的命令
for(key in state)
遍历数组
print key,”\t”,state[key]
打印数组的键和值,中间用\t制表符分割,美化一下。
如发现系统存在大量time_wait状态的连接,通过调整内核参数解决,
vim /etc/sysctl.conf
编辑文件,加入以下内容:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
然后执行 /sbin/sysctl -p 让参数生效。
linux下高并发的squid服务器,tcp time_wait套接字数量经常达到两、三万,服务器很容易被拖死。通过修改linux内核参数,可以减少squid服务器的time_wait套接字数量。
vi /etc/sysctl.conf
增加以下几行:引用
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 5000
说明:
net.ipv4.tcp_syncookies = 1 表示开启syn cookies。当出现syn等待队列溢出时,启用cookies来处理,可防范少量syn攻击,默认为0,表示关闭;
net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将time-wait sockets重新用于新的tcp连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1 表示开启tcp连接中time-wait sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout = 30 表示如果套接字由本端要求关闭,这个参数决定了它保持在fin-wait-2状态的时间。
net.ipv4.tcp_keepalive_time = 1200 表示当keepalive起用的时候,tcp发送keepalive消息的频度。缺省是2小时,改为20分钟。
net.ipv4.ip_local_port_range = 1024 65000 表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65000。
net.ipv4.tcp_max_syn_backlog = 8192 表示syn队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
net.ipv4.tcp_max_tw_buckets = 5000表示系统同时保持time_wait套接字的最大数量,如果超过这个数字,time_wait套接字将立刻被清除并打印警告信息。默认为 180000,改为5000。对于apache、nginx等服务器,上几行的参数可以很好地减少time_wait套接字数量,但是对于squid,效 果却不大。此项参数可以控制time_wait套接字的最大数量,避免squid服务器被大量的time_wait套接字拖死。
执行以下命令使配置生效:
/sbin/sysctl -p

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网