【发布时间】: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.phpheader('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);