Httpd 进程随着时间的推移使用更多内存

Httpd 进程随着时间的推移使用更多内存

我正在使用 3gb 内存的 VPS Centos 6 服务器。如果我重新启动它,我会运行大约 4 或 5 个 httpd 服务,它们都使用大约 2.5% 的内存(top 命令的 res 列上为 86m)。

我只运行一个尚未上线的网站,因此只有我一个人连接到该网站。

但是每天我都会看到 httpd 内存百分比增加 0.3 或 0.4(具体视情况而定)。这意味着 4 或 5 天后,这些 httpd 进程将使用大约 4% 的内存(top 命令中的 res 列为 130m)。我没有在日志中看到任何错误,并且一切正常,但如果我让服务器 2 周不重新启动,我就会耗尽内存。

例如,重现它的一种方法是使用 ab 命令。例如,如果我运行:

ab -c 2000 -t 60 http://xxx.xxx.xxx.xxx/

运行之后,每个 httpd 服务将比运行测试之前多使用大约 0.3 或 0.4 的内存。

我再次没有在日志中看到任何错误。

这是正常的吗?


我一直在做更多的测试和研究。我的价值观:

KeepAlive Off

<IfModule prefork.c>
StartServers       1
MinSpareServers    1
MaxSpareServers    5
ServerLimit        15
MaxClients        15
MaxRequestsPerChild  2000
</IfModule>

这似乎没问题,而且我始终有大约 500mb 的内存可用(至少在服务器刚刚重新启动时)。问题是始终处于活动状态的五个 httpd 进程的大小不断增加,因此当流量到达服务器并创建更多子进程时,它们将获得父 httpd 进程的大小。因此,如果父 httpd 进程为 120mb,则所有子进程都将为 120mb。因此,MaxRequestsPerChild 有多小并不重要,因为将创建一个新的子进程,它将占用与前一个进程一样多的内存。有什么建议吗?

答案1

你实际上没有说明你正在使用什么 Web 服务器软件。但是如果你正在谈论 Apache(并且它似乎可能采用多进程模型),那么你应该看看指令MaxRequestsPerChild

例如,如果您正在运行 php、ruby 或 perl 应用程序,这些应用程序(与大多数应用程序一样)对内存泄漏不是特别谨慎,那么您可能应该将 MaxRequestsPerChild 降低到 40 左右。不过,一个好的值确实会有所不同。有些应用程序堆栈与重新启动进程相关的成本比其他应用程序堆栈高得多,有些应用程序堆栈的内存泄漏问题比其他应用程序堆栈多得多。我在不同情况下将 MaxRequestsPerChild 设置为 5 到 1000 之间的任意值,但通常最好从低开始,然后在感觉安全时逐渐提高它。

在正常情况下,启动后内存使用量应该会有所增加,一段时间后就会趋于平稳。

如果您确实让服务器无人看管,并且内存不足,那么它很可能会开始使用交换,并且变得非常慢。由于请求无法快速处理,因此会堆积更多工作,并且除非进程数限制可以防止这种情况发生,否则它往往会消耗更多内存。您需要考虑一下进程数限制,以及您认为在这种情况下您的服务器会开始使用多少内存。

您也不希望有太多的交换空间。如果有大量的交换空间,您的服务器将或多或少完全没有响应,同时它会慢慢消耗其交换内存。要么您通过重新启动进行干预(您不太可能让 shell 工作),要么您将使用所有交换空间,并且 OOM Killer 将开始终止进程​​。如果到了这个地步,您实际上更希望 OOM Killer 尽快启动。过多的交换空间只会延长停机时间。对于大多数 Web 服务器来说,通常建议的交换空间是 RAM 的两倍,这是完全不合适的。

提高您的 minspareservers 和 maxspareservers。我会将最大值设置为 15 左右。低于这个值杀掉它们有什么意义?最小值至少应为 5。

答案2

你可能存在内存泄漏——如果持续增长每次运行ab测试时,大概有内存泄漏。(内存使用量略微超过首次启动服务器时的内存使用量是正常的。持续可预测的增长则不正常)。

如果你的问题是内存泄漏,那么可能不是网络服务器的错误,而是你的代码(PHP 或您使用的任何脚本语言,或者您所依赖的某些编写糟糕的库)。

修复内存泄漏的方法是分析你的代码(如何做到这一点是一个 Stack Overflow 问题),找到内存泄漏,并修复它(或者让负责泄漏代码的人员修复它)。


如果代码不透明(或者你没有时间)mc0e 的答案提供了一个可行的解决方法:确保您使用的是合适的 MPM(在 Unix 上,这意味着preforkworker),并设置MaxRequestsPerChild指令设置为足够低的值,以便在 RAM 耗尽之前回收您的工作人员。
此指令对性能有影响详细说明在文档中

答案3

最后我发现了问题所在。我的代码没有泄漏,也没有配置错误。系统运行正常。然而,问题与 Web 应用程序防火墙有关,它更新太频繁,每次更新时都会反复缓存规则,占用大量 httpd 内存。

谢谢大家

相关内容