技术频道


Apache 内存溢出假死问题的解决

httpd-mpm.conf 配置文件


Windows 下的 Apache 加载的是 mpm_winnt_module 部分的配置。 Apache 服务初始化后,内存里 new 出来 httpd.exe 的进程,对请求后线程分配一些资源(暂时不释放的),这样内存就开始飚升,如果用户长时间访问页面,内存就掉不下来了。因此,显示地设置了 MaxRequestsPerchild (每个子进程所处理的最大请求数)参数,希望它在每次处理完请求后,kill 掉进程,在重新创建,保持内存不会溢出。看了网络上有文章把 MaxRequestsPerchild 这个参数设置成 100,说是不会出现 httpd.exe 的死进程了,但经过测试把它从原来的0(无限制)改成了 100 后,问题稍微缓解,问题仍然存在,Apache 仍然会定期假死……

尤其是站点配置了 https 容易假死,而普通的 http 可以正常工作,经过不断的测试,最终发现参数 ThreadLimit:线程数限制,这个参数的设定值要和 ThreadPerChild 的值要一致, 以及 AcceptFilter https none,来看看下面配置。

# WinNT MPM
# ThreadsPerChild: constant number of worker threads in the server process
# MaxConnectionsPerChild: maximum number of connections a server process serves
<IfModule mpm_winnt_module>
    AcceptFilter http none   #注意这里
    AcceptFilter https none  #注意这里
    ThreadsPerChild   50
    ThreadLimit       50  #设置要和 ThreadPerChild 一致
    MaxConnectionsPerChild   500
</IfModule>

目前看,比较稳定,暂时没再出现假死情况。

Win32DisableAcceptEx 的坑


网上很多文章写的配置 Win32DisableAcceptEx,这其实是在 Apache 2.4 之前的版本,之后已经没有这个配置,应该是下面的:

AcceptFilter http none
AcceptFilter https none

FYI: Serverfault.com 解决 Apache 假死的原文参考:


After testing various configurations, we found out the problem and the server runs stable for 7 days now without any problems.

This settings in httpd.conf file fixed the problem:

AcceptFilter http none
AcceptFilter https none

Previously, we only had the AcceptFilter for http and the second line was missing.

According to Apache documentation the default values on Windows are:

AcceptFilter http data
AcceptFilter https data

Using none value uses accept() rather than AcceptEx() and will not recycle sockets between connections.

Apache 假死扩展阅读: