上周五(2011 年 10 月 7 日),我们发现 httpd.worker 进程在 1-2 分钟内从通常的 10-15M 内存保留增长到 10G+(千兆字节)。这显然会导致服务器停止运行,因为它开始交换等。我们必须重新启动服务器才能使其再次运行。如果我们及时发现问题,我们可以终止有问题的 httpd.worker,暂时一切都会好起来。
系统
- 红帽企业版 5.5
- Apache httpd-2.2.3-45.el5_6.2.x86_64.rpm(已修补以防止最近的字节范围过滤器漏洞)
- 使用 Apache MPM worker(不是 prefork)
- mod_jk 1.2.28
- mod_rewrite
- OpenSSL(最新红帽版本)
- Tomcat/JBoss Web 2.1(JBoss 5.1.0)
- 专用服务器(非共享),每台 12 GB 内存
症状
- 在正常负载下,一个 httpd.worker 进程的保留内存会突然从 10M 增长到几 GB。必须 kill -9 该进程,否则服务器会停止运行
- 偶尔会同时发生在多个 httpd.worker 进程中
- 一旦有问题的进程被终止,一切就会恢复正常(几分钟内)。
- 自上周五以来,每 8 - 12 小时就会发生一次,没有明显的规律。
- 请求流量没有激增
- access_log 和 error_log 中没有奇怪的流量/错误
补充笔记
- 我们的正常负载是每台服务器每秒约 5-10 个请求,不是很疯狂。
- 我们(在此之后)将 MaxRequestsPerChild 设置为 250,并且工作进程正在正常循环。这意味着问题出在单个或一小组请求上
- 在过去的两周内我们没有进行任何应用程序/系统配置更改。
- 由于这不是一个持续的问题(几分钟后就会消失),所以感觉不像是一个
- 这听起来就像字节范围过滤器漏洞,但我们已经修补并测试了它(https://issues.apache.org/bugzilla/show_bug.cgi?id=51714)
- 我读过几篇关于服务器故障(以及其他地方)的帖子,但没有发现任何一篇描述单个工作进程因内存失控的帖子
问题
- 什么原因会导致单个 httpd.worker 进程的内存增长如此失控?或者甚至超出正常范围(我们的配置为 10m-15m)?
- 有什么建议可以解决此问题吗?我们正在观察 top、server-status、jkstatus,使用 cacti 进行监控,安装了 monit,并且正在进行 mod_jk 日志记录。
Apache / mod_jk / Tomcat(JbossWeb)配置
从 httpd.conf...
<IfModule worker.c>
StartServers 2
MaxClients 500
MinSpareThreads 25
MaxSpareThreads 150
ThreadsPerChild 50
MaxRequestsPerChild 250
</IfModule>
来自 mod_jk 的 worker.properties……
# Define Node1 worker.node1.port=8009
worker.node1.host=127.0.0.1 worker.node1.type=ajp13
worker.node1.lbfactor=1 worker.node1.connection_pool_timeout=60
worker.node1.connection_pool_size=35 worker.node1.connect_timeout=5000
worker.node1.prepost_timeout=5000
从 tomcat 的 server.xml 中...
<Connector protocol="AJP/1.3" port="8009"
address="${jboss.bind.address}" redirectPort="8443" maxThreads="350"
connectionTimeout="60000" enableLookups="false"/>
非常感激您的意见!
答案1
我们已正式发现并修复了该问题,这只是 mod_rewrite 规则中的一个循环。它已经存在了几个月,但没有人点击导致该问题的特定 URL。因此,这至少是一些可能导致单个 httpd.worker 进程因内存消耗而失控的案例之一。