【问题标题】:Apache/PHP Internal Server Error (500) with possibility related to memory issueApache/PHP 内部服务器错误 (500),可能与内存问题有关
【发布时间】:2017-12-06 11:41:21
【问题描述】:

我刚搬到一个新的共享虚拟主机(PHP 7.0),把我所有的文件和数据从旧的移动了,然后我在我的新服务器上遇到了这个问题:

我有几个 PHP 页面(例如 mypage1.php),它们在客户端 webbrowser 中加载后,将加载另一个我的 PHP 页面(通过 XHR/XMLHttpRequest,例如 mypage2.php、mypage3.php、...、 mypage7.php) 来获取一些数据(比如说 JSON)。

当我尝试在我的浏览器中访问 mypage1.php 时,它会给出正确的响应,但是当浏览器尝试加载 mypage2.php, mypage3.php, ..., mypage7.php 时,它会返回“内部服务器错误 500 "(服务器错误日志:Mon Jul 03 01:50:07.747401 2017] [:error] [pid 612239:tid 139731694188288] (12)无法分配内存:[client xxxx:x] 无法创建子进程:/usr/ sbin/suphp 为 /xxx ...)。错误 500 仅出现在某些页面上(例如 mypage3.php 和 mypage6.php)

首先,我认为这只是一些 PHP 'memory_limit' 问题,所以我尝试通过重新配置(从 128M 增加)memory_limit 到 160M 然后 192M 来解决它,但它仍然失败。然后我尝试通过使用返回 4,194,304 的 memory_get_peak_usage(true)(它是从 mypage2.php - mypage7.php 获取的最大值)来找出我的 PHP 脚本消耗(或分配)多少内存。再次进行一些测试,错误似乎是随机发生的(有时所有页面都成功加载,有时 1 或 2 或 3 个页面失败并显示相同的错误消息)。

这让我想到,Apache 的 keep-alive 配置的可能性,所以我检查了它,它在 timeout=5 和 max=100 的情况下处于活动状态,所以我认为它还可以。但是,我仍然尝试设置HTTP 标头“连接:关闭”仍然没有给我任何解决方案。

然后,我尝试创建这个简单的脚本,并上传这个 'mypage1.php' 脚本:

<?php
$param1 = isset($_GET['param1'])? $_GET['param1'] : '';

if($param1==='')
echo('<html><head>
<script type="text/javascript" src="mypage1.php?param1=aaa" ></script>
<script type="text/javascript" src="mypage1.php?param1=bbb" ></script>
<script type="text/javascript" src="mypage1.php?param1=ccc" ></script>
<script type="text/javascript" src="mypage1.php?param1=ddd" ></script>
<script type="text/javascript" src="mypage1.php?param1=eee" ></script>
<script type="text/javascript" src="mypage1.php?param1=fff" ></script>
<script type="text/javascript" src="mypage1.php?param1=ggg" ></script>
</head><body>');
else echo('/* javascript */');
?>

这让我吃惊,即使是这个简单的脚本也会给我同样的错误 500 (... (12)Cannot allocate memory: ...) 这一次我遇到了死胡同。我不认为它与 PHP 内存问题有关(或者,你是这么认为的吗?)。请根据您的经验给我一些反馈、想法或任何故事,可能导致此问题的原因(或如何解决)。

编辑: 错误 500 仅在某些请求上发生(例如 mypage1.php?param1=ccc、mypage1.php?param1=fff)

谢谢

【问题讨论】:

  • 脚本类型需要 .js 文件资源而不是 php。在上面的示例中,javascript 页面的返回数据将具有 php 标头。
  • 您检查过 /var/log/apach2/errors.log 和 /var/log/php... 日志吗?检查是否记录了任何错误?您还必须检查您的内存状态,并请告诉我们您的操作系统
  • 如果您希望从 javascript 调用中运行 php,请使用 .htaccess 文件从请求的文件类型定向到 php,然后在您的 php 文件中,将标头输出为 javascript。 RewriteEngine On RewriteCond %{HTTPS} !=on RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] RewriteRule ^mypage1.js$ mypage1.php header('Content-Type: application/javascript');
  • @pokeybit 好观点,它应该有“标题 Content-Type:”到 text/javascript,以便客户端 Web 浏览器将响应识别为 javascript,但我认为不是这里的问题,因为某些请求(例如,mypage1.php?param1=aaa,mypage1.php?param1=bbb)返回 HTTP 200(尽管它应该按照您所说的进行更正),因为我在 webbrowser 网络控制台中看到它们。 (在我的生产问题案例中,返回 JSON 数据的是 PHP)
  • 代码在我的服务器上运行良好,没有错误 500。也许您的服务器正在限制连接,这会与您遇到的不一致有关,例如 param1=ccc 和 param1=fff 的错误,每两个调用 X 时间会导致阻塞。尝试添加echo('/* javascript */');sleep(1);

标签: php apache memory


【解决方案1】:

好的,我知道您想保护一些 javascript,对吧? 像这样进行验证是非常糟糕的主意,因为导入的(由参数返回)脚本可能太大而无法被浏览器和服务器读取。

它会抛出 HTTP 500,导致服务器无法解析那种大响应。

最好的解决方案是在 mypage1 中创建简单的开关,直接指向(并包含)请求的 javascript 文件:)

另外,您可以再创建 1 个 php 文件(用于 javascripts 的简单路由器),在此文件中您可以检查该参数 - 在此之后,您可以包含指定的 JS 或只返回 JS 文件名以将其包含在主 php 文件中: )

【讨论】:

  • 在我真正的 PHP 脚本中,“javascript 请求”是对我的另一个 PHP 文件的 JSON XMLHttpRequest。我害怕我的目标不是保护我的javascript,我只是创建一个新的简单场景,它给出完全相同的错误,我认为某种“如果同一时间的1个相同连接请求超过限制,那么返回错误”。因为错误 500 是不一致的(有时发生在 2 个请求中,有时发生在 3 个请求中,等等)但我就是不知道是什么设置,或者在哪里(Apache 或 PHP)。有什么想法吗?
猜你喜欢
  • 2011-10-04
  • 1970-01-01
  • 2015-02-12
  • 2015-11-22
  • 2018-11-14
  • 2011-06-11
  • 1970-01-01
  • 2016-02-16
  • 1970-01-01
相关资源
最近更新 更多