首页 技术 正文
技术 2022年11月21日
0 收藏 369 点赞 2,641 浏览 17244 个字

http://www.xshell.net/linux/Linux_sysctl_conf.html

优化Linux内核sysctl.conf参数来提高服务器并发处理能力

Posted by 破冰 on 2013-6-11 10:17 Tuesday

PS:在服务器硬件资源额定有限的情况下,最大的压榨服务器的性能,提高服务器的并发处理能力,是很多运维技术人员思考的问题。要提高Linux系统下的负载能力,可以使用nginx等原生并发处理能力就很强的web服务器,如果使用Apache的可以启用其Worker模式,来提高其并发处理能力。除此之外,在考虑节省成本的情况下,可以修改Linux的内核相关TCP参数,来最大的提高服务器性能。当然,最基础的提高负载问题,还是升级服务器硬件了,这是最根本的。

Linux系统下,TCP连接断开后,会以TIME_WAIT状态保留一定的时间,然后才会释放端口。当并发请求过多的时候,就会产生大量的TIME_WAIT状态的连接,无法及时断开的话,会占用大量的端口资源和服务器资源。这个时候我们可以优化TCP的内核参数,来及时将TIME_WAIT状态的端口清理掉。

本文介绍的方法只对拥有大量TIME_WAIT状态的连接导致系统资源消耗有效,如果不是这种情况下,效果可能不明显。可以使用netstat命令去查TIME_WAIT状态的连接状态,输入下面的组合命令,查看当前TCP连接的状态和对应的连接数量:
#netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’
这个命令会输出类似下面的结果:
LAST_ACK 16
SYN_RECV 348
ESTABLISHED 70
FIN_WAIT1 229
FIN_WAIT2 30
CLOSING 33
TIME_WAIT 18098
我们只用关心TIME_WAIT的个数,在这里可以看到,有18000多个TIME_WAIT,这样就占用了18000多个端口。要知道端口的数量只有65535个,占用一个少一个,会严重的影响到后继的新连接。这种情况下,我们就有必要调整下Linux的TCP内核参数,让系统更快的释放TIME_WAIT连接。

用vim打开配置文件:#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

输入下面的命令,让内核参数生效:#sysctl -p

简单的说明上面的参数的含义:

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
#修改系統默认的 TIMEOUT 时间。

在经过这样的调整之后,除了会进一步提升服务器的负载能力之外,还能够防御小流量程度的DoS、CC和SYN攻击。

此外,如果你的连接数本身就很多,我们可以再优化一下TCP的可使用端口范围,进一步提升服务器的并发能力。依然是往上面的参数文件中,加入下面这些配置:
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.ip_local_port_range = 10000 65000
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 5000
#这几个参数,建议只在流量非常大的服务器上开启,会有显著的效果。一般的流量小的服务器上,没有必要去设置这几个参数。

net.ipv4.tcp_keepalive_time = 1200
#表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。
net.ipv4.ip_local_port_range = 10000 65000
#表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为10000到65000。(注意:这里不要将最低值设的太低,否则可能会占用掉正常的端口!)
net.ipv4.tcp_max_syn_backlog = 8192
#表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
net.ipv4.tcp_max_tw_buckets = 6000
#表示系统同时保持TIME_WAIT的最大数量,如果超过这个数字,TIME_WAIT将立刻被清除并打印警告信息。默 认为180000,改为6000。对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量,但是对于Squid,效果却不大。此项参数可以控制TIME_WAIT的最大数量,避免Squid服务器被大量的TIME_WAIT拖死。

内核其他TCP参数说明:
net.ipv4.tcp_max_syn_backlog = 65536
#记录的那些尚未收到客户端确认信息的连接请求的最大值。对于有128M内存的系统而言,缺省值是1024,小内存的系统则是128。
net.core.netdev_max_backlog = 32768
#每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。
net.core.somaxconn = 32768
#web应用中listen函数的backlog默认会给我们内核参数的net.core.somaxconn限制到128,而nginx定义的NGX_LISTEN_BACKLOG默认为511,所以有必要调整这个值。

net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216           #最大socket读buffer,可参考的优化值:873200
net.core.wmem_max = 16777216           #最大socket写buffer,可参考的优化值:873200
net.ipv4.tcp_timestsmps = 0
#时间戳可以避免序列号的卷绕。一个1Gbps的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种“异常”的数据包。这里需要将其关掉。
net.ipv4.tcp_synack_retries = 2
#为了打开对端的连接,内核需要发送一个SYN并附带一个回应前面一个SYN的ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK包的数量。
net.ipv4.tcp_syn_retries = 2
#在内核放弃建立连接之前发送SYN包的数量。
#net.ipv4.tcp_tw_len = 1
net.ipv4.tcp_tw_reuse = 1
# 开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接。

net.ipv4.tcp_wmem = 8192 436600 873200
# TCP写buffer,可参考的优化值: 8192 436600 873200
net.ipv4.tcp_rmem  = 32768 436600 873200
# TCP读buffer,可参考的优化值: 32768 436600 873200
net.ipv4.tcp_mem = 94500000 91500000 92700000
# 同样有3个值,意思是:
net.ipv4.tcp_mem[0]:低于此值,TCP没有内存压力。
net.ipv4.tcp_mem[1]:在此值下,进入内存压力阶段。
net.ipv4.tcp_mem[2]:高于此值,TCP拒绝分配socket。
上述内存单位是页,而不是字节。可参考的优化值是:786432 1048576 1572864

net.ipv4.tcp_max_orphans = 3276800
#系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。
如果超过这个数字,连接将即刻被复位并打印出警告信息。
这个限制仅仅是为了防止简单的DoS攻击,不能过分依靠它或者人为地减小这个值,
更应该增加这个值(如果增加了内存之后)。
net.ipv4.tcp_fin_timeout = 30
#如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。对端可以出错并永远不关闭连接,甚至意外当机。缺省值是60秒。2.2 内核的通常值是180秒,你可以按这个设置,但要记住的是,即使你的机器是一个轻载的WEB服务器,也有因为大量的死套接字而内存溢出的风险,FIN- WAIT-2的危险性比FIN-WAIT-1要小,因为它最多只能吃掉1.5K内存,但是它们的生存期长些。

经过这样的优化配置之后,你的服务器的TCP并发处理能力会显著提高。以上配置仅供参考,用于生产环境请根据自己的实际情况。

http://tech.uc.cn/?p=1790

​1. SYN Flood介绍

前段时间网站被攻击多次,其中最猛烈的就是TCP洪水攻击,即SYN Flood。

SYN Flood是当前最流行的DoS(拒绝服务攻击)与DDoS(分布式拒绝服务攻击)的方式之一,这是一种利用TCP协议缺陷,发送大量伪造的TCP连接请求,常用假冒的IP或IP号段发来海量的请求连接的第一个握手包(SYN包),被攻击服务器回应第二个握手包(SYN+ACK包),因为对方是假冒IP,对方永远收不到包且不会回应第三个握手包。导致被攻击服务器保持大量SYN_RECV状态的“半连接”,并且会重试默认5次回应第二个握手包,塞满TCP等待连接队列,资源耗尽(CPU满负荷或内存不足),让正常的业务请求连接不进来。

详细的原理,网上有很多介绍,应对办法也很多,但大部分没什么效果,这里介绍我们是如何诊断和应对的。

2. 诊断

我们看到业务曲线大跌时,检查机器和DNS,发现只是对外的web机响应慢、CPU负载高、ssh登陆慢甚至有些机器登陆不上,检查系统syslog:

# tail -f /var/log/messages
Apr 18 11:21:56 web5 kernel: possible SYN flooding on port 80. Sending cookies.

检查连接数增多,并且SYN_RECV 连接特别多:
# netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’ 
TIME_WAIT 16855
CLOSE_WAIT 21
SYN_SENT 99
FIN_WAIT1 229
FIN_WAIT2 113
ESTABLISHED 8358
SYN_RECV 48965
CLOSING 3
LAST_ACK 313

根据经验,正常时检查连接数如下:
# netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’ 
TIME_WAIT 42349
CLOSE_WAIT 1
SYN_SENT 4
FIN_WAIT1 298
FIN_WAIT2 33
ESTABLISHED 12775
SYN_RECV 259
CLOSING 6
LAST_ACK 432

以上就是TCP洪水攻击的两大特征。执行netstat -na>指定文件,保留罪证。

3. 应急处理

根据netstat查看到的对方IP特征:
# netstat -na |grep SYN_RECV|more

利用iptables临时封掉最大嫌疑攻击的IP或IP号段,例如对方假冒173.*.*.*号段来攻击,短期禁用173.*.*.*这个大号段(要确认小心不要封掉自己的本地IP了!)
# iptables -A INPUT -s  173.0.0.0/8  -p tcp  –dport 80 -j DROP

再分析刚才保留的罪证,分析业务,用iptables解封正常173.*.*.*号段内正常的ip和子网段。这样应急处理很容易误伤,甚至可能因为封错了导致ssh登陆不了服务器,并不是理想方式。

4. 使用F5挡攻击

应急处理毕竟太被动,因为本机房的F5比较空闲,运维利用F5来挡攻击,采用方式:让客户端先和F5三次握手,连接建立之后F5才转发到后端业务服务器。后来被攻击时F5上看到的现象:
1. 连接数比平时多了500万,攻击停止后恢复。
2. 修改F5上我们业务的VS模式后,F5的CPU消耗比平时多7%,攻击停止后恢复。
3. 用F5挡效果明显,后来因攻击无效后,用户很少来攻击了,毕竟攻击也是有成本的。

5. 调整系统参数挡攻击

没有F5这种高级且昂贵的设备怎么办?我测试过以下参数组合能明显减小影响,准备以后不用F5抗攻击。

第一个参数tcp_synack_retries = 0是关键,表示回应第二个握手包(SYN+ACK包)给客户端IP后,如果收不到第三次握手包(ACK包)后,不进行重试,加快回收“半连接”,不要耗光资源。

不修改这个参数,模拟攻击,10秒后被攻击的80端口即无法服务,机器难以ssh登录; 用命令netstat -na |grep SYN_RECV检测“半连接”hold住180秒;

修改这个参数为0,再模拟攻击,持续10分钟后被攻击的80端口都可以服务,响应稍慢些而已,只是ssh有时也登录不上;检测“半连接”只hold住3秒即释放掉。

修改这个参数为0的副作用:网络状况很差时,如果对方没收到第二个握手包,可能连接服务器失败,但对于一般网站,用户刷新一次页面即可。这些可以在高峰期或网络状况不好时tcpdump抓包验证下。

根据以前的抓包经验,这种情况很少,但为了保险起见,可以只在被tcp洪水攻击时临时启用这个参数。

tcp_synack_retries默认为5,表示重发5次,每次等待30~40秒,即“半连接”默认hold住大约180秒。详细解释:

The tcp_synack_retries setting tells the kernel how many times to retransmit the SYN,ACK reply to
an SYN request. In other words, this tells the system how many times to try to establish a passive
TCP connection that was started by another host.
This variable takes an integer value, but should under no circumstances be larger than 255 for the
same reasons as for the tcp_syn_retries variable. Each retransmission will take aproximately 30-40
seconds. The default value of the tcp_synack_retries variable is 5, and hence the default timeout
of passive TCP connections is aproximately 180 seconds.

之所以可以把tcp_synack_retries改为0,因为客户端还有tcp_syn_retries参数,默认是5,即使服务器端没有重发SYN+ACK包,客户端也会重发SYN握手包。详细解释:

The tcp_syn_retries variable tells the kernel how many times to try to retransmit the initial SYN
packet for an active TCP connection attempt.
This variable takes an integer value, but should not be set higher than 255 since each
retransmission will consume huge amounts of time as well as some amounts of bandwidth. Each
connection retransmission takes aproximately 30-40 seconds. The default setting is 5, which
would lead to an aproximate of 180 seconds delay before the connection times out.

第二个参数net.ipv4.tcp_max_syn_backlog = 200000也重要,具体多少数值受限于内存。

以下配置,第一段参数是最重要的,第二段参数是辅助的,其余参数是其他作用的:
# vi /etc/sysctl.conf

 

1234567891011121314151617181920 #最关键参数,默认为5,修改为0 表示不要重发net.ipv4.tcp_synack_retries = 0#半连接队列长度net.ipv4.tcp_max_syn_backlog = 200000 #系统允许的文件句柄的最大数目,因为连接需要占用文件句柄fs.file-max = 819200#用来应对突发的大并发connect 请求net.core.somaxconn = 65536#最大的TCP 数据接收缓冲(字节)net.core.rmem_max = 1024123000 #最大的TCP 数据发送缓冲(字节)net.core.wmem_max = 16777216#网络设备接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目net.core.netdev_max_backlog = 165536#本机主动连接其他机器时的端口分配范围net.ipv4.ip_local_port_range = 10000 65535 # ……省略其它……

使配置生效:
# sysctl -p

注意,以下参数面对外网时,不要打开。因为副作用很明显,具体原因请google,如果已打开请显式改为0,然后执行sysctl -p关闭。因为经过试验,大量TIME_WAIT状态的连接对系统没太大影响:

 

12345678 #当出现 半连接 队列溢出时向对方发送syncookies,调大 半连接 队列后没必要net.ipv4.tcp_syncookies = 0#TIME_WAIT状态的连接重用功能net.ipv4.tcp_tw_reuse = 0#时间戳选项,与前面net.ipv4.tcp_tw_reuse参数配合net.ipv4.tcp_timestamps = 0#TIME_WAIT状态的连接回收功能net.ipv4.tcp_tw_recycle = 0

为了处理大量连接,还需改大另一个参数:
# vi /etc/security/limits.conf

在底下添加一行表示允许每个用户都最大可打开409600个文件句柄(包括连接):
*                –       nofile          409600

6. 参考资料

文件句柄不要超过系统限制/usr/include/linux/fs.h,相关链接: ​http://blog.yufeng.info/archives/1380
#define NR_OPEN (1024*1024)     /* Absolute upper limit on fd num */

内核参数详细解释:http://www.frozentux.net/ipsysctl-tutorial/chunkyhtml/tcpvariables.html

7. 结束语

TCP洪水攻击还没完美解决方案,希望本文对您有所帮助,让您快速了解。

 http://www.guoweiwei.com/archives/728

内核的优化跟服务器的优化一样,应本着稳定安全的原则。下面以64位的Centos5.5下的Squid服务器为例来说明,待客户端与服务器端建立TCP/IP连接后就会关闭SOCKET,服务器端连接的端口状态也就变为TIME_WAIT了。那是不是所有执行主动关闭的SOCKET都会进入TIME_WAIT状态呢?有没有什么情况使主动关闭的SOCKET直接进入CLOSED状态呢?答案是主动关闭的一方在发送最后一个ACK后就会进入TIME_WAIT状态,并停留2MSL(Max Segment LifeTime)时间,这个是TCP/IP必不可少的,也就是“解决”不了的。

  TCP/IP的设计者如此设计,主要原因有两个:

  防止上一次连接中的包迷路后重新出现,影响新的连接(经过2MSL时间后,上一次连接中所有重复的包都会消失)。

  为了可靠地关闭TCP连接。主动关闭方发送的最后一个ACK(FIN)有可能会丢失,如果丢失,被动方会重新发FIN,这时如果主动方处于CLOSED状态,就会响应RST而不是ACK。所以主动方要处于TIME_WAIT状态,而不能是CLOSED状态。另外,TIME_WAIT并不会占用很大的资源,除非受到攻击。

  在Squid服务器中可输入查看当前连接统计数的命令,如下所示:

12345678 #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
01020304050607080910 CLOSED:无连接是活动的或正在进行中的。LISTEN:服务器在等待进入呼叫。SYN_RECV:一个连接请求已经到达,等待确认。SYN_SENT:应用已经开始,打开一个连接。ESTABLISHED:正常数据传输状态。FIN_WAIT1:应用说它已经完成。FIN_WAIT2:另一边已同意释放。CLOSING:两边同时尝试关闭。TIME_WAIT:另一边已初始化一个释放。LAST_ACK:等待所有分组死掉。

  也就是说,这条命令可以把当前系统的网络连接状态分类汇总。

  在Linux下高并发的Squid服务器中,TCP TIME_WAIT套接字数量经常可达两三万,服务器很容易就会被拖死。不过,我们可以通过修改Linux内核参数来减少Squid服务器的TIME_WAIT套接字数量,命令如下所示:

1 #vim /etc/sysctl.conf

  然后, 增加以下参数:

123456789 #适用于Squid服务器net.ipv4.tcp_fin_timeout = 30net.ipv4.tcp_keepalive_time = 1200net.ipv4.tcp_syncookies = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_tw_recycle = 1net.ipv4.ip_local_port_range = 1024 65000 net.ipv4.tcp_max_syn_backlog = 8192net.ipv4.tcp_max_tw_buckets = 5000

其中各参数含义如下:

12345678 net.ipv4.tcp_syncookies=1表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookie来处理,可防范少量的SYN攻击。默认为0,表示关闭。net.ipv4.tcp_tw_reuse=1表示开启重用。允许将TIME-WAIT套接字重新用于新的TCP连接。默认为0,表示关闭。net.ipv4.tcp_tw_recycle=1表示开启TCP连接中TIME-WAIT套接字的快速回收。默认为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套接字拖死。

  执行以下命令使内核配置立即生效:

1 #/sbin/sysctl -p

如果是用于Apache或Nginx等的Web服务器,或Nginx的反向代理,则只需要更改以下几项即可:

12345 #适用于Apache或Nginx等web服务器,或Nginx的反向代理net.ipv4.tcp_syncookies = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_tw_recycle = 1net.ipv4.ip_local_port_range = 1024 65000

如果是邮件服务器,则建议内核方案如下:

1234567 #适用于邮件服务器net.ipv4.tcp_fin_timeout = 30net.ipv4.tcp_keepalive_time = 300net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_tw_recycle = 1net.ipv4.ip_local_port_range = 5000 65000kernel.shmmax = 134217728

最后记得,执行sysctl -p命令市内核配置生效:

1 #/sbin/sysctl -p

附:本文摘自《构建高可用Linux服务器》一书第1版63页,部分文字有调整。

http://www.linuxde.net/2013/05/13600.html

我们这里应用的是CentOS5.3,并内核使用的是2.6.18-128.el5PAE #1 SMP 。修改部分TCP ,有的是为了提高性能与负载,但是存在降低稳定性的风险。有的则是安全方面的配置,则有可能牺牲了性能。

1.TCP keepalive TCP连接保鲜设置

echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_time
echo 15 > /proc/sys/net/ipv4/tcp_keepalive_intvl
echo 5 > /proc/sys/net/ipv4/tcp_keepalive_probes

keepalive是TCP保鲜定时器。当网络两端建立了TCP连接之后,闲置idle(双方没有任何数据流发送往来)了tcp_keepalive_time后,服务器内核就会尝试向客户端发送侦测包,来判断TCP连接状况(有可能客户端崩溃、强制关闭了应用、主机不可达等等)。如果没有收到对方的回答(ack包),则会在tcp_keepalive_intvl后再次尝试发送侦测包,直到收到对对方的ack,如果一直没有收到对方的ack,一共会尝试tcp_keepalive_probes次,每次的间隔时间在这里分别是15s, 30s, 45s, 60s, 75s。如果尝试tcp_keepalive_probes,依然没有收到对方的ack包,则会丢弃该TCP连接。

2. syn cookies设置

echo 0 > /proc/sys/net/ipv4/tcp_syncookies

在CentOS5.3中,该选项默认值是1,即启用syn cookies功能。我们建议先关闭,直到确定受到syn flood攻击的时候再开启syn cookies功能,有效地防止syn flood攻击。也可以通过iptables规则拒绝syn flood攻击。

3.TCP  连接建立设置

echo 8192 > /proc/sys/net/ipv4/tcp_max_syn_backlog
echo 2 > /proc/sys/net/ipv4/tcp_syn_retries
echo 2 > /proc/sys/net/ipv4/tcp_synack_retries

tcp_max_syn_backlog  SYN队列的长度,时常称之为未建立连接队列。系统内核维护着这样的一个队列,用于容纳状态为SYN_RESC的TCP连接(half-open connection),即那些依然尚未得到客户端确认(ack)的TCP连接请求。加大该值,可以容纳更多的等待连接的网络连接数。

tcp_syn_retries  新建TCP连接请求,需要发送一个SYN包,该值决定内核需要尝试发送多少次syn连接请求才决定放弃建立连接。默认值是5. 对于高负责且通信良好的物理网络而言,调整为2

tcp_synack_retries  对于远端SYN连接请求,内核会发送SYN+ACK数据包来确认收到了上一个SYN连接请求包,然后等待远端的确认(ack数据包)。该值则指定了内核会向远端发送tcp_synack_retires次SYN+ACK数据包。默认设定值是5,可以调整为2

4. TCP 连接断开相关设置

echo 30 >  /proc/sys/net/ipv4/tcp_fin_timeout
echo 15000 > /proc/sys/net/ipv4/tcp_max_tw_buckets
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle

tcp_fin_timeout 对于由本端主动断开连接的TCP连接,本端会主动发送一个FIN数据报,在收到远端ACK后,且并没有收到远端FIN包之前,该TCP连接的状态是FIN_WAIT_2状态,此时当远端关闭了应用,网络不可达(拔网张),程序不可断僵死等等,本端会一直保留状态为FIN_WAIT_2状态的TCP连接,该值tcp_fin_timeout则指定了状态为FIN_WAIT_2的TCP连接保存多长时间,一个FIN_WAIT_2的TCP连接最多占1.5k内存。系统默认值是60秒,可以将此值调整为30秒,甚至10秒。

tcp_max_tw_buckets 系统同时处理TIME_WAIT sockets数目。如果一旦TIME_WAIT tcp连接数超过了这个数目,系统会强制清除并且显示警告消息。设立该限制,主要是防止那些简单的DoS攻击,加大该值有可能消耗更多的内存资源。如果TIME_WAIT socket过多,则有可能耗尽内存资源。默认值是18w,可以将此值设置为5000~30000
tcp_tw_resue 是否可以使用TIME_WAIT tcp连接用于建立新的tcp连接。

tcp_tw_recycle 是否开启快带回收TIME_WAIT tcp连接的功能。

5. tcp 内存资源使用相参数设定

echo 16777216 > /proc/sys/net/core/rmem_max
echo 16777216 > /proc/sys/net/core/wmem_max
cat /proc/sys/net/ipv4/tcp_mem
echo “4096 65536 16777216″ > /proc/sys/net/ipv4/tcp_rmem
echo “4096 87380 16777216″ > /proc/sys/net/ipv4/tcp_wmem

rmem_max 定义了接收窗口可以使用的最大值,可以根据BDP值进行调节。
wmem_max 定义了发送窗口可以使用的最大值,可以根据BDP什值进行调整。
tcp_mem [low, pressure, high] TCP用这三个值来跟踪内存使用情况,来限定资源占用。通常情况下,在系统boot之时,内核会根据可用内存总数计算出这些值。如果出现了Out of socket memory,则可以试着修改这个参数。
1)low: 当TCP使用了低于该值的内存页面数时,TCP不会考滤释放内存。
2)pressure: 当TCP使用了超过该值的内存页面数量,TCP试图稳定其对内存的占用,进入pressure模式,直到内存消耗达于low值,退出该模式。
3)hight:允许所有tcp sockets用于排队缓冲数据报的内存页数。
tcp_rmem [min, default, max]
1)min 为每个TCP连接(tcp socket)预留用于接收缓冲的内存数量,即使在内存出现紧张情况下TCP socket都至少会有这么多数量的内存用于接收缓冲。
2)default 为TCP socket预留用于接收缓冲的内存数量,默认情况下该值影响其它协议使用的 rmem_default的值,所以有可能被rmem_default覆盖。
3)max 该值为每个tcp连接(tcp socket)用于接收缓冲的内存最大值。该值不会影响wmem_max的值,设置了选项参数 SO_SNDBUF则不受该值影响。
tcp_wmem [min, default, max] 如上(tcp_rmen)只不过用于发送缓存。

注:
1)可以通过sysctl -w 或者写入/etc/sysctl.conf永久保存
2)性能调优仅在于需要的时候进行调整,调整以后需要采集数据与基准测试数据进行比较。建议,不需要盲从地调整这些参数。

http://cpjsjxy.iteye.com/blog/2090386

主动发起关闭TCP链接端状态转换图 
linux内核参数sysctl.conf,TCP握手ack,洪水攻击syn,超时关闭wait(转)

上图是tcp连接主动关闭端的状态转换图: 
(1)应用层调用close函数发起关闭连接请求 
(2)发送FIN到对端,关闭写通道,自己进入FIN_WAIT1状态 
(3)等待对端的确认ACK到来,接受到ACK后进入FIN_WAIT2状态;如果在超时时间内没有收到确认ACK直接进入CLOSED状态 
(4)如果在FIN_WAIT1状态时收到了对端的FIN则进入CLOSING状态(双发都发出了关闭连接请求) 
(5)在FIN_WAIT2接受到了对端FIN后进入TIME_WAIT状态;如果在超时时间内没有收这个FIN则直接进入CLOSED状态 
(6)在TIME_WAIT状态等待2个MSL(2个报文最长存活周期)后进入CLOSED状态

被动关闭TCP链接端状态转换图

linux内核参数sysctl.conf,TCP握手ack,洪水攻击syn,超时关闭wait(转)

上图是tcp连接被动关闭方的状态转换图 
(1)收到对端FIN后,关闭读通道进入CLOSE_WAIT状态 
(2)在CLOSE_WAIT状态等待应用层调用close函数关闭连接 
(3)如果在超时时间内调用了close,则进入LAST_ACK状态;否则直接进入CLOSED状态 
(4)在LAST_ACK状态,发送FIN到对端并等待对端的确认ACK 
(5)如果在超时时间内收到了确认ACK则进入CLOSED状态,否则直接进入CLOSED状态

状态分析

FIN_WAIT1 
主动方调用close函数关闭连接后立刻进入FIN_WAIT1状态,此时只要收到对端确认ACK后马上会进入FIN_WAIT2状态。 
出现场景:主动方等待ACK过程中网络断掉了,导致长时间收不到ACK,主动方就会停留在CLOSE_WAIT1状态上(超时时间:一般默认60s超时)。此时我们可以使用netstat -anpt 命令看到这种状态。这个状态在实际的工作中很少见。

FIN_WAIT2 
主动端在等待对端FIN到来过程中,会一你直保持这个状态(超时时间:一般默认是60s)。由于网络中断,或者对端很忙还没来得及发送FIN、或者对端有bug忘记关闭连接等都会导致主动端长时间处于FIN_WAIT2状态。如果主动方发现大量FIN_WAIT2状态时,应该引起相关人员的注意,这可能是网络不稳、对端程序bug的表现。这个状态比较常见。

TIME_WAIT 
主动方收到对端的FIN后进入TIME_WAIT状态。然后发送最后一个确认ACK到对端。之后等待2个最大的报文存活周期,正常的关闭流程客户端TCP连接都会经过这个状态,最终进入CLOSED状态。所以我们使用netstat -anpt命令发现客户端有很多的TIME_WAIT,一般这是正常的现象。这个状态最常见。

CLOSING 
双发几乎同时都调用了close接口主动关闭连接,此时都进入了FIN_WAIT1状态。如果在FIN_WAIT1状态期望收到对方的ACK但却收到了对方的FIN,这时候双方都进入CLOSING状态。然后都给对方一个ACK确认,收到了ACK后就会进入CLOSED状态了。

CLOSE_WAIT 
这个状态表明TCP连接等待被关闭。只可能在被动方出现。如果被动方存在大量的CLOSE_WAIT状态需要因为我们的特别注意了。我们要仔细研究确认为什么被动方迟迟不愿关闭连接(或许是我们程序中的bug开启了连接,用完后却忘记关闭)

目前开发过程中遇到如下这个场景导致被动方有很多的CLOSE_WAIT状态: 
A是一个应用程序,B是一个tomcat服务器 
A开了一个连接Conn,发送请求给B 
A接受相应数据后没有调用Conn.close关闭连接,在A端垃圾回收这些Conn对象前,这些连接一直保持着 
B端的连接超时后会主动发起关闭连接请求给A,此时A进入了CLOSE_WAIT状态,B进入了FIN_WAIT2状态,由于A迟迟不发送FIN给B,B端触发timeout直接进入了CLOSED状态。 
这样一个场景B端由于有超时设置一个为60s,不会存在大量的FIN_WAIT2状态 
但是A端就会残留大量的CLOSE_WAIT状态(CLOSE_WAIT状态也有超时,但是太大,默认为43200s,详情见tcp_timeout_close_wait系统配置)。还好A端的java虚拟机的最大对内存配置较小,由于CLOSE_WAIT状态连接同样占用了内存资源,数量很多后就会触发垃圾回收,此时A端的CLOSE_WAIT的连接Conn对象就会被销毁了(同时内存和句柄、端口等资源也被释放了)

LAST_ACK 
当被动端调用close接口关闭连接后便会进入这个状态,同时发送一个FIN给对端。在接受对端的ACK确认后便会进入CLOSED状态,这个状态一般不易出现,除非网络中断,一般对端会很快给与响应的。这个状态只可能在被动端出现。

状态总结 
主动端可能出现的状态:FIN_WAIT1、FIN_WAIT2、CLOSING、TIME_WAIT 
被动端可能出现的状态:CLOSE_WAIT LAST_ACK

NOTE: 
(1)主动端出现大量的FIN_WAIT1时需要注意网络是否畅通、出现大量的FIN_WAIT2需要仔细检查程序为何迟迟收不到对端的FIN(可能是主动方或者被动方的bug)、出现大量的TIME_WAIT需要注意系统的并发量/socket句柄资源/内存使用/端口号资源等。 
(2)被动端出现大量的 CLOSE_WAIT 需要仔细检查为何自己迟迟不愿调用close关闭连接(可能是bug,socket打开用完没有关闭)

http://soarwilldo.blog.51cto.com/5520138/1337535

当连接数多时,经常出现大量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

使之生效#######################################################################################apache服务器的time_wait过多 fin_wait1过多等问题1。time_wait状态过多。   通常表现为apache服务器负载高,w命令显示load average可能上百,但是web服务基本没有问题。同时ssh能够登陆,但是反应非常迟钝。原因:最可能的原因是httpd.conf里面keepalive没有开,导致每次请求都要建立新的tcp连接,请求完成以后关闭,增加了很多 time_wait的状态。另,keepalive可能会增加一部分内存的开销,但是问题不大。也有一些文章讨论到了sysctl里面一些参数的设置可以改善这个问题,但是这就舍本逐末了。2。fin_wait1状态过多。fin_wait1状态是在server端主动要求关闭tcp连接,并且主动发送fin以后,等待client端回复ack时候的状态。fin_wait1的产生原因有很多,需要结合netstat的状态来分析。netstat -nat|awk ‘{print awk $NF}’|sort|uniq -c|sort -n上面的命令可以帮助分析哪种tcp状态数量异常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攻击、又或者最近的程序改动引起了问题。一般说来后者可能性更大,应该主动联系程序员解决。但是如果有某个ip连接数非常多,就值得注意了,可以考虑用iptables直接封了他。

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,953
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,478
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,290
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,107
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,739
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,773