Apache Tomcat 在 300 个连接后阻塞

Apache Tomcat 在 300 个连接后阻塞

我们在 EC2 上托管的 Tomcat 前面有一个 apache 网络服务器,实例类型是超大,具有 34GB 内存。

我们的应用程序处理大量的外部网络服务,并且我们有一个非常糟糕的外部网络服务,在高峰时段需要将近 300 秒才能响应请求。

在高峰时段,服务器在大约 300 个 httpd 进程时就会阻塞。ps -ef | grep httpd | wc -l =300

我已经在 Google 上搜索过并找到了许多建议,但似乎没有任何作用。以下是我所做的一些配置,这些配置直接取自在线资源。

我已经增加了 apache 和 tomcat 中最大连接数和最大客户端数的限制。以下是配置详细信息:

//阿帕奇

   <IfModule prefork.c>
    StartServers 100
    MinSpareServers 10
    MaxSpareServers 10
    ServerLimit 50000
    MaxClients 50000
    MaxRequestsPerChild 2000
    </IfModule>

//雄猫

    <Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
           connectionTimeout="600000"
           redirectPort="8443"
           enableLookups="false" maxThreads="1500"
           compressableMimeType="text/html,text/xml,text/plain,text/css,application/x-javascript,text/vnd.wap.wml,text/vnd.wap.wmlscript,application/xhtml+xml,application/xml-dtd,application/xslt+xml"
           compression="on"/>

//Sysctl.conf

 net.ipv4.tcp_tw_reuse=1
 net.ipv4.tcp_tw_recycle=1
 fs.file-max = 5049800
 vm.min_free_kbytes = 204800
 vm.page-cluster = 20
 vm.swappiness = 90
 net.ipv4.tcp_rfc1337=1
 net.ipv4.tcp_max_orphans = 65536
 net.ipv4.ip_local_port_range = 5000 65000
 net.core.somaxconn = 1024

我尝试了很多建议,但都徒劳无功。如何解决这个问题?我确信 m2xlarge 服务器应该可以处理超过 300 个请求,可能是我的配置出了问题。

仅当高峰时段以及有 300 个并发请求等待 [延迟 300 秒] Web 服务响应时,服务器才会阻塞。

我只是用 netstat 监控 tcp 连接

我发现大约有 1000 个连接处于 TIME_WAIT 状态,不知道这对性能意味着什么,我确信这一定会加剧问题。

TOP 的输出

 8902  root      25   0 19.6g 3.0g  12m S  3.3  8.8  13:35.77 java
 24907 membase   25   0  753m 634m 2528 S  2.7  1.8 285:18.88 beam.smp
 24999 membase   15   0  266m 121m 3160 S  0.7  0.3  51:30.37 memcached
 27578 apache    15   0  230m 6300 1536 S  0.7  0.0   0:00.03 httpd
 28551 root      15   0 11124 1492  892 R  0.3  0.0   0:00.25 top


 Output of free -m
 total       used       free     shared    buffers    cached
 35007       8470       26536    0          1         61
 8407        26599
 15999       15         15984

 output of iostat
 avg-cpu:  %user   %nice %system %iowait  %steal   %idle
      26.21    0.00    0.48    0.13    0.02   73.15

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda1             14.36         4.77       329.37    9005402  622367592
sdb               0.00         0.00         0.00       1210         48

另外,在高峰时段,到 membase 服务器[本地] 的 tcp 连接数约为 10-15k

MODJK LOG 中存在一些错误,我希望这可以为这个问题提供一些帮助。

[Wed Jul 11 14:39:10.853 2012] [8365:46912560456400] [error]         ajp_send_request::jk_ajp_common.c (1630): (tom2) connecting to backend failed. Tomcat is probably not started or is listening on the wrong port (errno=110)
[Wed Jul 11 14:39:18.627 2012] [8322:46912560456400] [error] ajp_send_request::jk_ajp_common.c (1630): (tom2) connecting to backend failed. Tomcat is probably not started or is listening on the wrong port (errno=110)
[Wed Jul 11 14:39:21.358 2012] [8351:46912560456400] [error] ajp_get_reply::jk_ajp_common.c (2118): (tom1) Tomcat is down or refused connection. No response has been sent to the client (yet)
[Wed Jul 11 14:39:22.640 2012] [8348:46912560456400] [error] ajp_get_reply::jk_ajp_common.c (2118): (tom1) Tomcat is down or refused connection. No response has been sent to the client (yet)

~

Worker.properties
workers.tomcat_home=/usr/local/tomcat/
worker.list=loadbalancer
worker.tom1.port=8009
worker.tom1.host=localhost
worker.tom1.type=ajp13
worker.tom1.socket_keepalive=True
worker.tom1.connection_pool_timeout=600
worker.tom2.port=8109
worker.tom2.host=localhost
worker.tom2.type=ajp13
worker.tom2.socket_keepalive=True
worker.tom2.connection_pool_timeout=600
worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=tom1,tom2
worker.loadbalancer.sticky_session=True
worker.tom1.lbfactor=1
worker.tom1.socket_timeout=600
worker.tom2.lbfactor=1
worker.tom2.socket_timeout=600

//解决了

感谢大家的宝贵建议..我错过了 AJP 1.3 连接器的 maxThreads 设置..现在一切似乎都在掌控之中。

我甚至还会开始研究像 nginx 这样的服务器。

答案1

您是否增加了端口 8009 上的 AJP 1.3 连接器中的 maxThreads?

答案2

考虑在 Apache 之前设置一个异步代理 Web 服务器。Apache 以同步方式提供内容,因此工作人员会被阻止,直到客户端下载完生成的内容为止(更多nginx详细信息lighttpd这里)。设置异步(非阻塞)代理通常可以大大改善情况(我曾经将同时运行的 Apache 工作程序的数量从 30 个降低到 3-5 个,用作nginx前端代理)。

答案3

无论如何,从您显示的日志来看,我怀疑您的问题出在 tomcat 而不是 apache 上。当您尝试重新连接 tomcat 时收到“错误 110”,这表明您有一个等待服务的连接队列,而 tomcat 中侦听套接字的侦听积压设置已无法容纳更多连接。

From the listen manpage:
   The  backlog  parameter defines the maximum length the queue of pending 
   connections may grow to.  If a connection request arrives with
   the queue full the client may receive an error with an indication
   of ECONNREFUSED or, if the underlying protocol supports  
   retransmission, the request may be ignored so that retries succeed.

如果一定要我猜的话,我会怀疑当服务器“阻塞”时,绝大多数 HTTP 请求都被阻塞,等待从 tomcat 返回某些内容。我敢打赌,如果您尝试获取由 apache 直接提供的一些静态内容(而不是通过代理到 tomcat),那么即使在正常情况下“阻塞”时,这种方法也能奏效。

不幸的是,我不熟悉 tomcat,但是有没有办法可以操纵它的并发设置?

哦,你可能还需要考虑外部网络服务限制连接数的可能性是在做给你降至 300,因此如果您建立的几乎每个连接都依赖于外部 Web 服务响应,那么您在前端进行多少并发操作都没有区别。

在您的一条评论中,您提到数据在 2 分钟后会过期。我建议将此服务获得的响应缓存两分钟,以减少您向外部 Web 服务发送的并发连接数量。

答案4

对于任何类型的企业部署,prefork MPM 几乎是你能做出的最糟糕的选择:它吞噬资源,而且与其他 MPM 相比,重新启动线程需要很长时间。

至少切换到工人MPM(apache 2.2 及以上版本)或者 - 更好的是 - 升级到当前稳定版本 2.4.2,并使用其默认事件最大行程长度。

这两者都能够以很少的开销轻松处理数千个并发连接。

相关内容