![mpm_prefork:错误无法分配内存](https://linux22.com/image/694613/mpm_prefork%EF%BC%9A%E9%94%99%E8%AF%AF%E6%97%A0%E6%B3%95%E5%88%86%E9%85%8D%E5%86%85%E5%AD%98.png)
我使用一个名为 loadimpact 的网站来测试我的 php 应用程序在大量访问下的表现。我做了一个非常小的测试,只有 50 个虚拟用户同时访问,我注意到一段时间后所有请求都返回了 502 状态代码。即使在测试完成后,我也无法再访问该网站,也收到 502 错误。在我重新启动服务器后,它恢复正常。
我检查了服务器日志并看到以下消息:
[mpm_prefork:error] [pid 3189] (12)Cannot allocate memory: AH00159: fork: Unable to fork new process
我猜想这是因为服务器内存不足,但我也不确定。我还注意到服务器 CPU 使用率在同一时间达到峰值。
服务器重启后我又进行了两次测试,一切运行正常,没有内存错误也没有 502 响应。
我的应用程序是使用 Laravel 构建的,我使用 AWS Elastic Beanstalk 作为我的 AWS 服务器,使用 RDS 实例作为我的数据库。它是一个 t2.micro 实例。我唯一的自定义配置是在后台运行计划任务的 crontab。
当我测试的页面被访问时,我基本上做三件事:我在数据库中记录访问情况,我设置一个 cookie 来跟踪用户,我从数据库中加载一些东西。
我原本计划测试服务器容量,因为我正在与一家更大的公司合作,这将为网站带来更多的访问量,但现在我担心这种情况再次发生,因为我不确定造成这种情况的原因。
有人知道是什么原因导致了这个错误吗?
答案1
这肯定是服务器内存不足的错误。对于负载下的 Apache/PHP 安装来说,t2.micro 相当拥挤。从数据库读取了多少“内容”?
我还看到过某些类型的应用程序错误导致 PHP 陷入无限递归错误,以至于无论多少内存都无法满足它的需求;无论你有多少内存,它所要求的内存量都会略少一些。
答案2
查看top
或ps aux
输出每个 Apache 进程使用的内存量。将其乘以 50,即可大致计算出为 50 个同时使用的用户提供服务所需的内存量。
使用带有 PHP 的 worker 或 event Apache MPM 作为单独的 CGI 进程池,而不是带有 mod_php 的 prefork MPM,可以帮助更有效地利用内存。
您还可以通过删除 Apache 模块和 PHP 扩展来减少内存使用量。您在 PHP 代码中执行的操作也会影响内存使用量,您可以使用 PHP 中的内存函数来分析这一点。
在某些时候,您必须选择具有更多 RAM 的实例类型或将负载分散到多个实例上。
答案3
这并不能解决您的问题,但它可以帮助您解决问题。
云计算的两大优点是弹性和自动化。弹性意味着如果您的服务器速度变慢或出现故障,您可以轻松启动另一台服务器或另外 50 台服务器。自动化意味着无需您直接输入即可完成所有操作。AWS Elastic Beanstalk 支持这两者。
你需要启用负载平衡和自动缩放和配置健康检查。这样,如果您的服务器开始返回错误代码,它将能够将流量路由到健康的服务器,停止故障服务器,并在其位置创建新的服务器。如果您需要 1 台服务器来处理您的负载,您可能需要保持 2 台服务器运行才能拥有可靠的系统。您可以将这些服务器放在不同的可用区中,以为自己拥有更可靠的系统,最好使用多可用区 RDS 数据库。
答案4
(这是一个老问题,但仍然有 Google 链接/今天出现在 Serverfault 首页上)。
有人知道是什么原因导致了这个错误吗?
所有内存都已用完。
除此之外,这主要是猜测,因为您没有提供太多关于如何配置的详细信息,也没有提供在 Web 服务器开始返回 502 错误时写入日志的内容。我猜您使用的是 PHP-FPM,而它被 OOM-killer 删除,导致出现 502 错误。
发生这种情况是因为您没有对 Web 服务器或 FPM 设置任何限制,或者将限制设置得太高。
只有 50 个虚拟用户
....不是一个有意义的指标。但它确实表明并发连接数相对较低,并意味着 PHP 内存使用率较高(或其他程序占用的内存较高,留给 PHP 的内存很少)。虽然应该可以在 1Gb RAM 中支持更高的并发连接数,但您仍然需要找到并设置适当的限制。