【问题标题】:Confusing PHP/AJAX timeout after 900 secs(15 mins)900 秒(15 分钟)后令人困惑的 PHP/AJAX 超时
【发布时间】:2014-12-12 19:26:55
【问题描述】:

以下所有内容均基于 Linux、最新的 Apache、最新的 Apache PHP 模块。

我的基于 AJAX+PHP 的 Web 应用程序出现意外行为。 这是一种非常简单的 AJAX 方法,基本上涉及对运行一段时间(几秒到几分钟)的 PHP 脚本 (execute.php) 的请求。作为测试设置,PHP 脚本 (execute.php) 基本上只是休眠一段时间。当这个数量是 899 秒时,它可以工作,但是当我将它设置为 900 时,PHP 脚本(简单 echo() )的答案似乎过期或类似的东西(究竟是什么原因或原因实际上是未知的我),因为请求没有注意到它,因此没有响应,并且相应的 innerHTML 没有按预期更新。 请在下面找到代码。

我现在想知道这个 900 秒的“超时”从何而来,更重要的是,我该如何防止这种情况发生?毕竟,我认为这至少是 AJAX 处理异步调用并在请求更改其状态时立即通知客户端的一个总体思路?!

进程.php

<?php
session_start();

include("functions.php");
include("env.php");

html_head("Processing...");

$sid = $_SESSION['my_sid'];

?>
<script type="text/javascript">
function run_analyses(params){
    <?php
    print "var sid = \"". $sid ."\";
    ";
    ?>

    // Use AJAX to execute the programs independenantly in the background
    // Allows for the user to close the process-page and come back at a later point to the results-link, w/o need to wait.
    if (window.XMLHttpRequest)
    {
        http_request = new XMLHttpRequest();
    }
    else
    {
        //Fallback for IE5 and IE6, as these don't support the above writing/code
        http_request = new ActiveXObject("Microsoft.XMLHTTP");
    }
    //Is http_request still false
    if (!http_request)
    {
        alert('Ende :( Kann keine XMLHTTP-Instanz erzeugen');
    }

    http_request.onreadystatechange=function(){
        if (http_request.readyState==4 && http_request.status==200){
            // Maybe used to display the progress of the execution
            document.getElementById("output").innerHTML=http_request.responseText;
        }
    };

    http_request.open("POST","execute.php",true);
    //Send the proper header information along with the request
    http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    http_request.setRequestHeader("Content-length", params.length);
    http_request.setRequestHeader("Connection", "close");
    http_request.send(params);
};
</script>

<?php
$params "some_params";
print "
Starting AJAX-call<br>
<div style=\"width:400px; border: 1px black solid;\" id=\"output\">Use this to display an information about the progress</div>
<script type=\"text/javascript\">
    run_analyses('".$params."');
</script>
<form action=\"./usersets/". $sid ."/results.html\" id=\"go_to_results\" method=\"POST\">
<input type='hidden' name=\"session_id\" value=\"" .$sid. "\">
</form>
";
html_foot();
?>

并执行.php:

<?php

session_start();

include("functions.php");
include("env.php");

$sid = $_SESSION['my_sid'];

// Used to get the time at start of processing
$time = microtime();
$time = explode(' ', $time);
$time = $time[1] + $time[0];
$start = $time;
session_write_close();

sleep(900);  //899 here works

session_start();
$time = microtime();
$time = explode(' ', $time);
$time = $time[1] + $time[0];
$finish = $time;
$total_time = round(($finish - $start), 3);
//echo 'Page generated in '.$total_time.' seconds.'."\n";

// Make it accessible for the results
$_SESSION['process_time'] = $total_time;

echo("none");

?>

因此,当 PHP 脚本休眠 899 秒时,“开始 AJAX 调用”之后的文本会更新为“无”,但如果该值为 900 秒,则保持“使用它来显示有关进度的信息”。

我非常期待您的建议。

最好的,

影子

编辑

执行grep max_execution $(locate php.ini ) 给出:

/etc/php5/apache2/php.ini:max_execution_time = 30
/usr/share/doc/php5-common/examples/php.ini-development:max_execution_time = 30
/usr/share/doc/php5-common/examples/php.ini-production:max_execution_time = 30
/usr/share/php5/php.ini-production:max_execution_time = 30
/usr/share/php5/php.ini-production-dist:max_execution_time = 30
/usr/share/php5/php.ini-production.cli:max_execution_time = 30

EDIT2 有趣的是,在我的浏览器中本地调用脚本(在我的本地 linux 机器上运行的 apache 网络服务器)时,它的行为符合预期并尊重请求的返回。但它在运行在不同机器上的网络服务器上运行时会出现上述意外行为。有什么线索吗?因为我没有……对不起。

【问题讨论】:

  • 你检查你的 php.ini 设置了吗?最大执行时间?
  • 直接加载您的代码(不是从 JS 加载)并启用错误显示...检查它显示的内容。
  • 编辑了我的帖子,表明它似乎与 max_execution_time 相关。
  • 在我的回答中查看编辑#2
  • @lepe:我没有显示任何错误-在本地,脚本在 900 秒后返回,但在远程,它似乎没有返回,或者至少 AJAX 请求没有注意到它。我不确定原因等。

标签: php javascript html ajax


【解决方案1】:

在你的 php.ini 中有一个max_execution_time,默认是 30 秒,所以它似乎在某个地方设置为 900。所以我会先检查那里。信息:http://www.php.net/manual/en/info.configuration.php#ini.max-execution-time

至于解决它,您可以编辑 php.ini 以将该值设置为非常高(或 0 表示无限制),或者您也可以使用此功能:http://php.net/manual/en/function.set-time-limit.php 在 300 秒后重置它。

希望这会有所帮助!

编辑:添加 Lee 的 0 值 max_execution_time 的建议

编辑 2:

刚刚在这里http://www.php.net/manual/en/function.set-time-limit.php#75557发现了一些有趣的东西

请注意,在 Linux 下,睡眠时间被忽略,但在 Windows 下,它计入执行时间。

所以,这可能就是为什么它允许执行超过 30 秒,但最终仍将其切断。

【讨论】:

  • 设置max_execution_time = 0,表示执行时间不受限制。
  • 请看上面:编辑了我的帖子,表明它似乎与 max_execution_time 无关。
  • 看到了编辑,有一个复杂的因素,Linux 上 max_execution_time 的睡眠被忽略(因为没有真正执行),请参阅我的编辑 #2
  • 请记住,DoS 可以真正杀死具有无限执行时间的服务器。
【解决方案2】:

我尝试了您的示例并将其放置在不同的主机(不是本地主机)中。就我而言,它运行良好并在 900 秒后得到“无”值。我删除了 SESSION 调用以简化示例...

无需会话即可尝试。如果这改变了一些东西,那么“session.cookie_lifetime”值可能是相关的。

【讨论】:

    【解决方案3】:

    在您的所有php.ini.htaccess 中搜索值900:

    grep -HR 900 $(locate php.ini ) $(locate -e .htaccess )
    

    同时在您的源代码中搜索 900 和 900 的小数:

    cd /var/www/ #path_to_yoursite
    grep --color=auto -HR "=\s*900\b"
    grep --color=auto -HR "=\s*20\s*\*\s*45\b"
    grep --color=auto -HR "=\s*15\s*\*\s*60\b"
    ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-02
      • 2011-10-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多