柔中带刚,刚中带柔,淫荡中富含柔和,刚猛中荡漾风骚,无坚不摧,无孔不入!
全部博文(1669)
分类:
2012-10-19 16:09:20
2012-10-15 17:05:35| 分类: rhel_apache | 标签: |字号大中小
问题是80的apache转发到8080的apache时失败:
[error] (99)Cannot assign requested address: proxy: HTTP: attempt to connect to 127.0.0.1:8080 (*) failed
netstat里time wait太多导致了[error] (99)Cannot assign requested address
sysctl -w net.ipv4.tcp_tw_recycle=1 表示开启TCP连接中TIME-WAIT sockets的快速回收
改了这个参数在观察:apache不报错了,time wait数也降了
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套接字拖死。..
对于处理并发量较高的Server,统计会发现本机tcp的time_wait状态的连接非常多
netstat -nat | awk '{++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 24413
established) 1
SYN_SENT 1
FIN_WAIT1 1
State 1
ESTABLISHED 15
LAST_ACK 1
LISTEN 7
该time_wait的默认值为2*MSL,MSL即max segment lifetime,是一个tcp包的最大生存时间
MSL值在Linux上好像默认是30秒,所以从time_wait状态变化到CLOSED大约需要60s时间
另外一方面,本机可用的发起连接的socket端口是有限的,可通过以下命令查看
cat /proc/sys/net/ipv4/ip_local_port_range
32768 61000
也即大约只有2万多个端口可用,如果处于 time_wait状态的连接很多
很有可能会影响本机向外发起的连接(比如说nginx的proxy服务器),出现端口不够用的情况
可以通过以下参数去减少time_wait的连接
vi /etc/sysctl.conf
#开启time_wait状态的socket重用
net.ipv4.tcp_tw_reuse = 1
#开启time_wait状态的socket快速回收
net.ipv4.tcp_tw_recycle = 1
/sbin/sysctl -p
或者直接修改time_wait的等待时间
echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
更多的Linux内核优化可参见
今天检查了一下基本一台服务器,发现TIME_WAIT高到3k多.TIME_WAIT本身并不会占用很大资源的,除非受到攻击.但太多服务器还是有可能挂掉.
TIME_WAIT 3699
CLOSE_WAIT 52
FIN_WAIT1 32
SYN_SENT 1
FIN_WAIT2 2
ESTABLISHED 17
SYN_RECV 45
CLOSING 6
根据《TCP/IP详解》中的TCP的建立和终止中有关"TCP的终止"的讲解
TCP的终止通过双方的四次握手实现.发起终止的一方执行主动关闭,响应的另一方执行被动关闭.
1. 发起方更改状态为FIN_WAIT_1,关闭应用程序进程,发出一个TCP的FIN段;
2. 接收方收到FIN段,返回一个带确认序号的ACK,同时向自己对应的进程发送一个文件结束符EOF,同时更改状态为CLOSE_WAIT,发起方接到ACK后状态更改为FIN_WAIT_2;
3. 接收方关闭应用程序进程,更改状态为LAST_ACK,并向对方发出一个TCP的FIN段;
4. 发起方接到FIN后状态更改为TIME_WAIT,并发出这个FIN的ACK确认.ACK发送成功后(2MSL内)双方TCP状态变为CLOSED.
我们不难看出上面的显示的结果的意思.根据TCP协议,主动发起关闭的一方,会进入TIME_WAIT状态(TCP实现必须可靠地终止连接的两个方向(全双工关闭)),持续2*MSL(Max Segment Lifetime),缺省为240秒.
为什么 TIME_WAIT 状态需要保持 2MSL 这么长的时间?
TIME_WAIT的等待时间为2MSL,即最大段生存时间.如果 TIME_WAIT 状态保持时间不足够长(比如小于2MSL),第一个连接就正常终止了.第二个拥有相同相关五元组的连接出现(因为连接终止前发起的一方可能需要重发 ACK,所以停留在该状态的时间必须为MSL的2倍.),而第一个连接的重复报文到达,干扰了第二个连接.TCP实现必须防止某个连接的重复报文在连接终 止后出现,所以让TIME_WAIT态保持时间足够长(2MSL),连接相应方向上的TCP报文要么完全响应完毕,要么被丢弃.建立第二个连接的时候,不 会混淆.
注:MSL(最大分段生存期)指明TCP报文在Internet上最长生存时间,每个具体的TCP实现都必须选择一个确定的MSL值.RFC 1122建议是2分钟,但BSD传统实现采用了30秒.TIME_WAIT 状态最大保持时间是2 * MSL,也就是1-4分钟.
对apache的操作
HTTP协议1.1版规定default行为是Keep-Alive,也就是会重用TCP连接传输多个request/response.所以我打开 http中的keepalive On,发现TIME_WAIT就立刻少了下来.只有300的样子.总结一下.我认为有二个原因.
1.keepalive没有开,导致每次请求都要建立新的tcp连接,请求完成以后关闭,增加了很多time_wait的状态,没有重 用,KeepAlive我认为它指的是保持连接活跃,类似于Mysql的永久连接.如果将KeepAlive设置为On,那么来自同一客户端的请求就不需 要再一次连接,避免每次请求都要新建一个连接而加重服务器的负担.
2.然后keepalive在系统中本身的值很高.默认空闲连接 7200 秒(2 小时)内没有活动.才会断开.
我们开启KeepAlive:
KeepAlive On
MaxKeepAliveRequests 120
KeepAliveTimeout 15
这样每个连接可以发送100次请求,超时时间为15秒(如果第二次请求和第一次请求之间超过KeepAliveTimeOut的时间的话,第一次连接就会中断,再新建第二个连接).
有关内核级别的keepalive和time_wait的优化调整
vi /etc/sysctl
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_keepalive_time = 1800
net.ipv4.tcp_fin_timeout = 30
net.core.netdev_max_backlog =8096
修改完记的使用sysctl -p 让它生效
以上参数的注解
/proc/sys/net/ipv4/tcp_tw_reuse
该文件表示是否允许重新应用处于TIME-WAIT状态的socket用于新的TCP连接.
/proc/sys/net/ipv4/tcp_tw_recycle
recyse是加速TIME-WAIT sockets回收
对tcp_tw_reuse和tcp_tw_recycle的修改,可能会出现.warning, got duplicate tcp line warning, got BOGUS tcp line.上面这二个参数指的是存在这两个完全一样的TCP连接,这会发生在一个连接被迅速的断开并且重新连接的情况,而且使用的端口和地址相同.但基本 上这样的事情不会发生,无论如何,使能上述设置会增加重现机会.这个提示不会有人和危害,而且也不会降低系统性能,目前正在进行工作
/proc/sys/net/ipv4/tcp_keepalive_time
表示当keepalive起用的时候,TCP发送keepalive消息的频度.缺省是2小时
/proc/sys/net/ipv4/tcp_fin_timeout 最佳值和BSD一样为30
fin_wait1状态是在发起端主动要求关闭tcp连接,并且主动发送fin以后,等待接收端回复ack时候的状态.对于本端断开的socket连接,TCP保持在FIN-WAIT-2状态的时间.对方可能会断开连接或一直不结束连接或不可预料的进程死亡.
/proc/sys/net/core/netdev_max_backlog
该文件指定了,在接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目.
tcp状态
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:没有任何连接状态