许久没来,不知道csdn有没有高手进入。。
问题:
apache2.2,内负载,前端F5负载到两台服务器21,22,分别做apache内负载-单台机单个apache托三个tomcat,在大并发情况下,发现大量tcp close_wait假死等待关闭,而且一直维持在此状态。导致请求堆积,出现超时错误。。netstat发现close_wait端口为在apache与tomcat之间的连接状态。。如下:
tcp        1      0 192.168.83.22:32454         192.168.83.22:8408          CLOSE_WAIT  
tcp        1      0 192.168.83.22:32506         192.168.83.22:8408          CLOSE_WAIT  
tcp        1      0 192.168.83.22:32267         192.168.83.22:8408          CLOSE_WAIT  
tcp        1      0 192.168.83.22:32297         192.168.83.22:8408          CLOSE_WAIT 
等等。。通过命令
[chaichunyi@localhost ~]$ netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'
TIME_WAIT        205
CLOSE_WAIT       1082
FIN_WAIT1        1
FIN_WAIT2        279
ESTABLISHED      811
LAST_ACK         1
可见大量close_wait端口被占用。。workers配置如下:
worker.t22a.port=XXXX
worker.t22a.host=XXX
worker.t22a.type=ajp13
worker.t22a.lbfactor=1
worker.t22a.connection_pool_size=1500
worker.t22a.connection_pool_timeout=20
worker.t22a.socket_timeout=180
worker.t22a.socket_connect_timeout=180000
worker.t22a.socket_keepalive=1tomcat ajp3协议配置:
<Connector port="8409" protocol="AJP/1.3" 
                maxThreads="2000" bufferSize="4096" enableLookups="false"
                backlog="2000" connectionTimeout="20000" redirectPort="8443"
                URIEncoding="UTF-8" />apache关键配置:
Timeout 60
KeepAlive On
MaxKeepAliveRequests 400
KeepAliveTimeout 3<IfModule mpm_prefork_module>
    StartServers        50
    MinSpareServers     50
    MaxSpareServers     300
    ServerLimit         6000
    MaxClients          5000
    MaxRequestsPerChild 15000
</IfModule>解决方案尝试:
已优化了服务器内核参数还是无法解决,如下:
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1
net.ipv4.tcp_keepalive_time=1800
net.ipv4.tcp_keepalive_probes=4
net.ipv4.tcp_keepalive_intvl=15请问谁有做过大并发的apache配置?提供点意见和建议。。谢谢!!

解决方案 »

  1.   

    这个问题比较复杂,不是一下子就有必然能解决的方案的。从你描述上来说,CLOSE_WAIT 发生在Tomcat和Apache之间,
    那么你可以尝试关闭HTTP1.1协议下的新特性:KeepAlive 
    Tomcat的位置是在server.xml 中的Connector 元素中。另外,Apache内核参数可以再适当调低(慎重慎重):
    sysctl -w net.ipv4.tcp_keepalive_probes=2
    sysctl -w net.ipv4.tcp_keepalive_intvl=2
      

  2.   

    对了,HTTP1.1协议的KeepAlive跟 TCP协议的keepalive,完全不是一个东西,请注意。
      

  3.   

    学习了,ldh911很厉害,6个月连拿第一了,仰视了,希望我以后也能懂这么多!哈哈!
      

  4.   

    关于这个keepalive参数。。在中午的时候我已经关闭了。。由于我是在本机。。无须此属性,具体的作用不明显(正常)。。
    关于内核参数,你说的那个实在有点闷。。由于我keepalive已关闭,所以内核参数也用不着改了。。
      

  5.   

    这是我现在的配置:
    worker.t22a.port=XX
    worker.t22a.host=XXX
    worker.t22a.type=ajp13
    worker.t22a.lbfactor=1
    worker.t22a.connection_pool_size=1(官方提示apache2.2,prefork模式不能超过1,因为本身没有用到连接池)
    worker.t22a.connection_pool_timeout=20
    worker.t22a.socket_timeout=120
    #worker.t22a.socket_connect_timeout=20000(默认和socket_timeout一样)
    #worker.t22a.recovery_options=3
    #worker.t22a.socket_keepalive=1(apache和tomcat在一台机器,无须此属性)最新的情况还在测试中,4楼的老兄还有没有其他的建议可以一起探讨。。这问题。。困扰我快一周了。。
    再来点高手啊。
      

  6.   

    说明一下。。apache的keepalive没有关闭。还是上面的配置。。
      

  7.   

    你确定 Tomcat的keepalive关闭了么?俺说的不是Apache,是Tomcat。因为你是用Apache做反向代理去连接Tomcat,此时提供keepalive能力的是Tomcat;Apache的keeplive是提供给连接Apache的浏览器或压力测试机服务的。