参考:
当连接数多时,经常出现大量fin_wait1,可以修改 /etc/sysctl.conf
修改
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_keepalive_time = 30
net.ipv4.tcp_window_scaling = 0
net.ipv4.tcp_sack = 0
然后:
/sbin/sysctl -p
使之生效
#######################################################################################
原因:最可能的原因是httpd.conf里面keepalive没有开,导致每次请求都要建立新的tcp连接,请求完成以后关闭,增加了很多 time_wait的状态。另,keepalive可能会增加一部分内存的开销,但是问题不大。也有一些文章讨论到了sysctl里面一些参数的设置可以改善这个问题,但是这就舍本逐末了。
2。fin_wait1状态过多。fin_wait1状态是在server端主动要求关闭tcp连接,并且主动发送fin以后,等待client端回复ack时候的状态。fin_wait1的产生原因有很多,需要结合netstat的状态来分析。
netstat -nat|grep ":80"|awk '{print $5}' |awk -f: '{print $1}' | sort| uniq -c|sort -n
则可以帮助你将请求80服务的client ip按照连接数排序。
回到fin_wait1这个话题,如果发现fin_wait1状态很多,并且client ip分布正常,那可能是有人用肉鸡进行ddos攻击、又或者最近的程序改动引起了问题。一般说来后者可能性更大,应该主动联系程序员解决。
在linux下查看apache的负载情况,以前也说过,最简单有有效的方式就是查看(如何点这里),在没有开启apache server status的情况下,或安装的是其他的web server,比如nginx的时候,下面的命令就体现出作用了。
ps -ef|grep httpd|wc -l命令
#ps -ef|grep httpd|wc -l
1388
统计httpd进程数,连个请求会启动一个进程,使用于apache服务器。
表示apache能够处理1388个并发请求,这个值apache可根据负载情况自动调整,我这组服务器中每台的峰值曾达到过2002。
netstat -nat|grep -i "80"|wc -l命令
#netstat -nat|grep -i "80"|wc -l
4341
netstat -an会打印系统当前网络链接状态,而grep -i “80″是用来提取与80端口有关的连接的, wc -l进行连接数统计。
最终返回的数字就是当前所有80端口的请求总数。
netstat -na|grep established|wc -l命令
#netstat -na|grep established|wc -l
376
netstat -an会打印系统当前网络链接状态,而grep established 提取出已建立连接的信息。 然后wc -l统计。
最终返回的数字就是当前所有80端口的已建立连接的总数。
netstat -n | awk '/^tcp/ { s[$nf]} end {for(a in s) print a, s[a]}'命令
#netstat -n | awk '/^tcp/ { s[$nf]} end {for(a in s) print a, s[a]}'
fin_wait_1 286
fin_wait_2 960
syn_sent 3
last_ack 32
closing 1
closed 36
syn_rcvd 144
time_wait 2520
established 352
这条语句是在张宴那边看到,据说是从新浪互动社区事业部技术总监王老大那儿获得的,非常不错。返回参数的说明如下:
syn_recv表示正在等待处理的请求数;
established表示正常数据传输状态;
time_wait表示处理完毕,等待超时结束的请求数。
tag: , ,
kimi at 2008-09-01 03:01:08 in ,
解决linux下大量的time_wait问题
vi /etc/sysctl.conf
编辑/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.route.gc_timeout = 100
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
说明:
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,表示关闭。
再执行以下命令,让修改结果立即生效:
引用
/sbin/sysctl -p
用以下语句看了一下服务器的tcp状态:
引用
netstat -n | awk '/^tcp/ { s[$nf]} end {for(a in s) print a, s[a]}'
返回结果如下:
established 1423
fin_wait1 1
fin_wait2 262
syn_sent 1
time_wait 962
效果:处于time_wait状态的sockets从原来的10000多减少到1000左右。处于syn_recv等待处理状态的sockets为0,原来的为50~300。
通过上面的设置以后,你可能会发现一个新的问题,就是netstat时可能会出现这样的警告:
引用
warning, got duplicate tcp line
这正是上面允许tcp复用产生的警告,不过这不算是什么问题,总比不允许复用而给服务器带来很大的负载合算的多
尽管如此,还是有解决办法的:
1、 安装rpm包:
[root@root2 opt]# rpm -uvh net-tools-1.60-62.1.x86_64.rpm
preparing... ########################################### [100%]
1:net-tools ########################################### [100%]
[root@root2 opt]#
对于下载的是源码的rpm则需要使用以下方法安装:
2、 安装rpm源码包方法:
a) 安装src.rpm:
# [root@root1 opt]# rpm -i net-tools-1.60-62.1.src.rpm
……
b) 制作rpm安装包:
[root@root1 opt]# cd /usr/src/redhat/specs/
[root@root1 specs]# rpmbuild -bb net-tools.spec
c) rpm包的升级安装:
[root@root1 specs]# pwd
/usr/src/redhat/specs
[root@root1 specs]# cd ../rpms/x86_64/
[root@root1 x86_64]# rpm -uvh net-tools-1.60-62.1.x86_64.rpm
3、 再使用netstat来检查时系统正常:
说明:
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套接字拖死。
net.ipv4.route.gc_timeout = 100 路由缓存刷新频率, 当一个路由失败后多长时间跳到另一个
默认是300
net.ipv4.tcp_syn_retries = 1 对于一个新建连接,内核要发送多少个 syn 连接请求才决定放弃。不应该大于255,默认值是5,对应于180秒左右。
netstat -n | awk '/^tcp/ { s[$nf]} end {for(a in s) print a, s[a]}'