查找超出文件末尾的位置会导致 Apache 挂起,并且永远不会重新启动

查找超出文件末尾的位置会导致 Apache 挂起,并且永远不会重新启动

我实际上已经用更好的脚本解决了我的问题,但我仍然想知道为什么 Apache2 完全挂起 - 这是一个开箱即用的 ISPCONFIG 3.03 安装,一切都是最新的,运行完美。直到...

麻烦但看似无害的脚本:

$fp = fopen("/var/log/ispconfig/cron.log", "r");
fseek($fp, -5000, SEEK_END);
$line_buffer = array();
while (!feof($fp)) {
    $line = fgets($fp, 1024);
    $line_buffer[] = $line;
    $line_buffer = array_slice($line_buffer, -10, 10);
}
foreach ($line_buffer as $line) {
echo $line;
}

您明白我的意思,这只是我在论坛上找到的一个脚本。我对各种日志都这样做了,因为它是一个很好的窗口,可以方便地查看正在发生的事情(当然是在受保护的目录中!)。

有一天,日志变得越来越大,我已经整理好了所有的 cron、脚本和邮件队列错误,我想我是时候重新开始了。更新、重新启动、存档并删除了日志。几个小时后,当我运行脚本时,它挂了。挂了。我等了 8 分钟。当然,Chrome 会将页面超时,但服务器再也没有恢复。htop 显示 /usr/sbin/apache2 -k restart 使用 100% CPU。直到我执行 service apache2 restart 后才恢复。运行正常,但当我再次访问该日志文件时...死机了。

因此,我发现这是日志文件脚本的问题,我发现在文件末尾进行搜索并不好,于是我找到了一个更好的脚本http://www.php.net/manual/en/function.fseek.php#90450

但让我疑惑的是...为什么没有重新启动或终止进程?一个挂起的页面怎么能使整个服务器瘫痪?它正在运行 suphp。我说的是“开箱即用”,我已经调整了 mysql 和 apache,以便为 VPS 的 512Mb RAM 分配和保留合理数量的进程,它将处理大页面的多次刷新,并且之前没有挂起过。

有什么想法可以避免这种情况吗?除了上面关于进程数与可用 RAM 的推荐之外,Google 在本例中不是我的朋友。

答案1

默认情况下,Apache 和操作系统都不会猜测脚本的执行时间。有一个 rlimit 系统工具可以解决此类问题,mod_cgi 会公开该工具来控制脚本的执行时间(但 mod_cgid 不会)。

Apache 也使用固定数量的线程/进程,如果您将它们全部用在等待永远不会到来的 I/O 上,它最终将无法接受新的连接。

相关内容