300次连接后Apache Tomcat阻塞


16

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

我们的应用程序处理许多外部Web服务,而我们的外部Web服务非常糟糕,在高峰时段需要近300秒才能响应请求。

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

我已经在Google上搜索,发现了很多建议,但似乎没有任何效果。

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

// apache

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

// tomcat

    <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日志中存在一些错误,我希望这能为您解决这个问题。

[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

//解决了

thansk提出您的宝贵建议。.我错过了AJP 1.3连接器的maxThreads设置。.现在一切似乎都在控制之中。

我也将开始关注甚至基于nginx的服务器。


您的Keepalive设置是什么样的?
汤姆·奥康纳

客户端尝试加载页面时会返回哪种错误?
Shane Madden

1
您是否增加了apache / httpd用户的最大允许打开文件描述?
golja

@Tom My Keep Alive设置为httpd.conf中的KeepAliveTimeout 10
john titus 2012年

3
top在这段时间内,look 的输出是什么样的?怎么free -m样 最后iostat呢?
Zypher

Answers:


13

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


1500是我每个tomcat实例所拥有的
john titus 2012年

@john,您是说为每个连接器指定了maxThreads =“ 1500”吗?您可以为AJP 1.3连接器(端口8009)发布节吗?
HTTP500 2012年

感谢您指出这一点..根本没有AJP1.3的maxThreads设置..这可能是原因吗?
约翰·蒂瑟斯

1
是的,将maxThreads添加到该连接器的节中。默认值是200
HTTP500

6

考虑设置一个异步代理Web服务器,例如Apache nginxlighttpd在Apache前面。Apache同步提供内容,因此工作人员将被阻止,直到客户端完全下载生成的内容为止(此处有更多详细信息)。设置一个异步(非阻塞)代理通常会大大改善这种情况(我曾经使用nginx前端代理将同时运行的Apache worker的数量从30个减少到3-5个)。


5

我从您显示的日志中怀疑您的问题出在tomcat而不是Apache。当您遇到“错误110”尝试重新连接到tomcat时,表明您有等待等待提供的连接队列,再也无法容纳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服务的并发连接数。


2

解决此问题的第一步是启用Apache的mod_status并研究其报告-在您完成此操作之前,实际上您是在盲目走动。那不是正义的。;-)

提到的第二件事(我自己不喜欢被告知我没有问的问题的答案,但是...)正在使用更高效,更特殊的前端服务器,例如nginx

另外,你究竟restart阿帕奇,或者只是gracefulLY 重载呢?:)


Apache重新启动..不是正常的重载
john titus 2012年

好吧,@ johntitus mod_status是你的朋友。:)
poige 2012年

1

对于任何类型的企业级部署,prefork MPM都是您可以做出的最糟糕的选择:与其他MPM相比,它吞噬了像没人一样的业务之类的资源,并且重新启动线程要花很多时间。

至少切换到工作程序 MPM(Apache 2.2及更高版本),或者-更好地-升级到具有其默认事件 MPM 的当前稳定版本2.4.2 。

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


谢谢..也尝试过..没有运气。TIME_WAIT连接不断增加。服务器在350个连接处停止响应
john titus 2012年

1
我不同意这是最糟糕的选择-在这种情况下,这是一个糟糕的选择,使用线程服务器可以缓解问题,但更好的解决方案是使用基于事件的服务器(nginx或lighttpd)。基于事件的Apache还不够成熟,无法从企业部署恕我直言中考虑。
symcbean 2012年

1

我知道这是一个古老的故事,但我有两句话。

有一个硬编码限制将ServerLimit指令。 http://httpd.apache.org/docs/2.2/mod/mpm_common.html#serverlimit您会看到最大为20000 / 200K。

编译到服务器中的ServerLimit 20000有一个硬限制(对于前叉MPM 200000)。这样做是为了避免错别字引起的令人讨厌的影响。

第二显然nodybo提到将那两个设置为一个是一个非常糟糕的主意

net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1

这意味着您提前重用timewait,您猜怎么着?服务器可能会在高负载下与错误的客户端通信。

我找到了一篇很好的文章来解释这一点,但是-是法语;-) http://vincent.bernat.im/fr/blog/2014-tcp-time-wait-state-linux.html


0

超大容量,具有34GB内存。

大铁不是扩展Web服务的方法,您只是在解决瓶颈问题。但是,即使有这么多的内存,我仍怀疑50000个连接是否在推动系统的能力,特别是在以下情况下:

在高峰时段,服务器仅阻塞约300个httpd进程

如果您解释“服务器阻塞”的含义,将很有帮助。

具有如此高的连接限制,但具有极低的磁滞限制(最小/最大备用服务器)也很奇怪。

尽管您提供的错误摘要并未显示“太多打开的文件”,但我还是先看一下打开文件描述符的数量和ulimit设置。


服务器扼流圈在它不回应,甚至普通的HTML文件..
约翰·泰特斯

我现在将maxClients更改为3000 ..仍然是同样的问题
约翰·蒂斯


0

这更像是一条评论,但是不能,因为我的声誉不高。遇到了与@john titus完全相似的问题。

我们使AJP连接器MaxThreads接近我们的Apache Thread限制来解决该问题。

为了监视此情况,我们在AJP端口上通过netstat命令寻求了SYN_SENT netstat端口状态帮助

netstat -an | grep :8102 | grep SYN_SENT | wc -l

下降到0,这总是比AJP连接器上设置的MaxThread限制大一些。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.