我的 Apache 2.2 模块(Windows)似乎占用内存很大,任务管理器显示内存不断增长,直到达到约 2GB,然后崩溃。我根本没有使用 PHP,这不是一个网站,而是一个充当服务器的模块。许多条形码扫描设备将向此服务器发送请求,该服务器将对数据库进行插入、更新、删除和查询。如果我有 10-15 个设备同时工作,就会看到这个问题。
我正在使用 FastMM 检测 Apache 模块中的内存泄漏,但 FastMM 没有报告任何泄漏。如果我故意引入一个,我可以看到 FastMM 捕获到泄漏。
这说明 Apache 没有向操作系统释放内存,这种情况只在某些情况下发生。如果我只有 1-2 个设备,则不会发生此问题。因此,我猜测这是由于向 Apache 发送的请求数量过多造成的。
作为临时解决方案,我使用 PowerShell(版本 2.0 或 4.0,取决于机器)脚本在达到内存阈值时重新启动 Apache。我的 PowerShell 脚本正在执行此操作以停止 Apache 进程和服务并启动它(如果内存已达到约 0.8GB),这一切都有效,我对其进行了测试:
# If working set of httpd or httpd#1 is greater than threshold, stop and start
if($procobj.workingset -gt $Threshold)
{
# $ProcName is name of process reported by PowerShell (as httpd, httpd#1, httpd#2, ...)
echo $("Memory for " + $ProcName + " exceeds Threshold");
# Stop httpd process
stop-process -name $MyHTTPD -force
# Stop service $ServiceName (this is name of service in Windows->Services)
echo $("---> Stopping service: " + $ServiceName);
stop-Service $ServiceName;
# Start service $ServiceName (this is name of service in Windows->Services)
echo $("---> Starting service: " + $ServiceName);
start-Service $ServiceName;
}
如您所见,我正在停止 httpd 进程,然后停止 Apache 服务,然后启动将产生新 httpd 进程的服务。
另外,以下是我正在使用的 Apache 设置:
#Commented out these 3 in httpd.conf
#KeepAlive On
#MaxKeepAliveRequests 0
#KeepAliveTimeout 3000
#these are in mod_mpm
# WinNT MPM
<IfModule mpm_winnt_module>
ThreadsPerChild 300
#MaxRequestsPerChild 0
MaxRequestsPerChild 50
#According to Apache documentation, if you get "An operation was
#attempted on something that is not a socket), you should use this to
#disable AcceptEx() WinSock v2 API. See:
# http://httpd.apache.org/docs/2.2/mod/mpm_winnt.html
Win32DisableAcceptEx
</IfModule>
我知道这应该是临时解决方案,但现在的问题是,尽管任务管理器显示内存不断增长,但我无法检测到任何泄漏。因此,我正在寻找通过正常重启来最大程度地减少影响的方法。我不确定我上面的 Apache 设置是否足够好,我是否缺少一些可以帮助我的设置。我也不确定我的 powershell 是否会正常重启,所以我正在寻找有关如何处理此问题的建议。
我也在 error.log 中看到很多这样的条目
[warn] pid file C:/Handheld/Apache2/logs/httpd.pid overwritten -- Unclean shutdown of previous Apache run?
,我相信这可能是由于我的脚本重新启动 Apache 造成的。
非常感激,