Apache连接后的Tomcat扼stream圈

我们在EC2托pipe的Tomcat前面有一个apache webserver,实例types是34GB内存的超大型。

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

在繁忙时间,服务器扼制了大约300个httpd进程。 ps -ef | grep httpd | wc -l = 300

我GOOGLE了,发现了很多build议,但似乎没有任何工作..以下是我已经做了一些configuration,直接从网上资源。

我已经增加了最大的连接和最大的客户端在Apache和Tomcat的限制。 这里是configuration细节:

//阿帕奇

<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 

我一直在尝试很多build议,但徒劳无功。如何解决这个问题? 我敢肯定m2xlarge服务器应该比300更多的请求,可能我可能会出错我的configuration..

服务器只在繁忙时间和当有300个并发请求等待[300秒延迟] Web服务响应。

我只是用netstat监视TCP连接

我发现在TIME_WAIT状态下有大约1000个连接,不知道在性能方面会有什么意义,我相信它肯定会增加这个问题。

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 

另外在高峰时间有大约10-15k的tcp连接到membase服务器[local]

在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这样的基础服务器。

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

考虑在Apache之前设置一个像nginxlighttpd这样的asynchronous代理Web服务器。 Apache同步地提供内容,所以工作人员被阻止,直到客户完全下载生成的内容(更多细节在这里 )。 设置一个asynchronous(非阻塞)代理通常可以显着改善情况(我曾经使用nginx作为前端代理,将同时运行的Apache worker的数量从30个减less到了3-5个)。

我怀疑你的问题是在tomcat不是阿帕奇,从你已经显示的日志。 当你得到'错误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,但有没有办法来操纵这个并发设置?

噢,你可能还需要考虑一下这样的可能性,即它的外部networking服务将所做的连接数量限制在300以内,所以在你的前端进行多less并发操作并没有什么不同如果几乎每个连接都依靠外部Web服务响应。

在您提到的其中一个评论中,数据在2分钟后变得陈旧。 我build议caching你从这个服务获得的响应两分钟,以减less你正在驱动到外部Web服务的并发连接数量。

解决这个问题的第一步是启用Apache的mod_status并研究它的报告 – 直到你做完这个,实际上你是盲目地走路。 这不正确。 😉

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

另外,你刚刚restart Apache,或只是graceful 重新加载它? 🙂

对于任何types的企业级部署,prefork MPM都是您可以做的最糟糕的select:像任何人的业务一样吞噬资源,重新启动线程与其他MPM相比需要花费更多的时间。

至less切换到MPM工作站(apache 2.2或更高版本),或者更好的是,升级到当前的稳定版本2.4.2,其默认事件 MPM。

这两者都可以轻松处理数千个并发连接,而​​且开销很小。

超大内存34GB。

大铁不是衡量Web服务能力的一种方式,你只是在移动瓶颈。 但即使有了这么多的内存,我怀疑有50000个连接正在推动系统的function,尤其是:

在繁忙时间,服务器扼制了大约300个httpd进程

如果你用“服务器扼stream器”来解释你的意思,这将会很有帮助。

拥有如此高的连接限制,但迟滞极限(最小/最大备用服务器)也是非常奇怪的。

虽然你提供的错误提取不会显示“太多打开的文件”,我会先看看打开的文件描述符的数量和ulimit设置。

也许Apache用户正在用尽文件句柄? 你的post中没有提到他们。 Apache目前有多less个文件句柄?

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

ServerLimit指令有一个硬编码限制http://httpd.apache.org/docs/2.2/mod/mpm_common.html#serverlimit你会发现它是最大的20000 / 200K。

将ServerLimit 20000编译到服务器(用于prefork MPM 200000)有一个硬限制。 这是为了避免错别字造成的恶意效果。

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

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

这意味着你重新使用了等待时间,猜猜看是什么? 服务器可能会在重负载下与错误的客户端进行通信。

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