![未充分利用的 Apache 服务器提高了 MaxRequestWorkers 的上限:内存泄漏?](https://linux22.com/image/652065/%E6%9C%AA%E5%85%85%E5%88%86%E5%88%A9%E7%94%A8%E7%9A%84%20Apache%20%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%8F%90%E9%AB%98%E4%BA%86%20MaxRequestWorkers%20%E7%9A%84%E4%B8%8A%E9%99%90%EF%BC%9A%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F%EF%BC%9F.png)
在具有 1GB RAM 的 Ubuntu 服务器上,采用默认配置的 Apache 2.4.7 服务器偶尔会停止响应请求。它用于个人云 + 其他需求和低流量网站。
通过对 error.log 的检查,我们发现每次问题出现时,都会出现这样的重复模式:
[mpm_prefork:error] [pid 31950] AH00161: server reached MaxRequestWorkers setting, consider raising the MaxRequestWorkers setting
之后access.log
根本不会记录任何访问。然后一天后:
[mpm_prefork:notice] [pid 31950] AH00171: Graceful restart requested, doing restart
这显然并没有什么区别。
我每次都必须手动重启服务器。
现在我正在查看mpm_prefork.conf
,这是默认值,从我能够收集的信息来看,我认为我不需要更改任何内容。我开始怀疑可能存在一些内存泄漏,并读到这MaxConnectionsPerChild 1000
是一种防止内存泄漏的黑客行为,所以我将它设置为 1000 这个值,看看它的表现如何。由于这是偶尔发生的错误,因此很难确切地了解是什么导致了问题。
您是否认为MaxConnectionsPerChild
在这种情况下使用是一种好的策略(希望在我托管的网站的进一步发布中修复内存泄漏),或者这仅仅表明没有内存泄漏?
注意:由于平均 Apache 进程消耗约 20Mb 内存,我将 MaxRequestWorkers 从 150 减少到 30(考虑到服务器上有 500Mb 内存可供 Apache 使用)。我现在有:
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxRequestWorkers 30
MaxConnectionsPerChild 1000
</IfModule>
我不认为记忆达到了顶峰,但由于我的 Munin 客户端关闭,我现在意识到,我无法排除它。
答案1
从我的文档根目录中删除 Owncloud 8.0.0 是最终答案。之后 Apache 就可以按预期工作了...
不过,如果能了解问题的原因以及如何配置 Apache,以便它能够处理有问题的 PHP 应用程序,那就更好了。令人失望的是,MaxConnectionsPerChild
在这种情况下无法处理这个问题,但同样,我不确定到底发生了什么,即使MaxRequestWorkers
错误日志似乎表明线程数量是问题所在。
答案2
也许我的情况太特殊了,我遇到了同样的server reached MaxRequestWorkers setting
错误,并认为我的网站流量也很低。否则日志就很枯燥了。我发现了一篇帖子,上面说我可以将 Apache 的日志级别从“警告”提高到“调试”,所以我更改了它,希望能收集到一些有用的东西。当/var/log/apache2/error.log
我重新启动 Apache 时,我正在跟踪,输出立即爆发成无休止的滚动混乱。我无法阅读它,因为它移动得太快了。我确实注意到每 1000 行左右就有一行正常行,但其余行都相同——全部来自俄罗斯 IP。我的第一个 DOS!
我读到过,你可以使用 iptables 中的一行来丢弃来自特定 ip 的数据包。我运行了两行,滚动就停止了——太冷了。
iptables -A INPUT -s <ip address here> -j DROP
iptables -A INPUT -s <ip address here> -j DROP
关于如何缓解 DOS 攻击,有很多很好的资源,但对我来说,我还不知道我受到了 DOS 攻击。跟踪这个[mpm_prefork:error]
线索是我的重大突破。我确信并非每个 prefork 错误都是 DOS 攻击,但也许这篇文章可以帮助某些人!
https://linuxaria.com/howto/how-to-verify-ddos-attack-with-netstat-command-on-linux-terminal
答案3
您是否可能有一堆进程在等待对 apache 的子请求,而这些进程确保 apache 永远不会有多余的进程来应答?
重要的是,对同一服务器上的任何 URL 的调用都会有超时。