linux上PHP的实际最大执行时间



根据文档:

max_execution_time only affect the execution time of the script itself. 
Any time spent on activity that happens outside the execution of the script
such as system calls using system(), stream operations, database queries, etc.
is not included when determining the maximum time that the script has been running.
This is not true on Windows where the measured time is real.

通过测试证实:

不会超时

<?php
set_time_limit(5);
$sql = mysqli_connect('localhost','root','root','mysql');
$query = "SELECT SLEEP(10) FROM mysql.user;";
$sql->query($query) or die($query.'<br />'.$sql->error);
echo "You got the page";

将超时

<?php
set_time_limit(5);
while (true) {
  // do nothing
}
echo "You got the page";

我们的问题是,我们真的希望PHP在给定的时间后超时,无论它在做什么(因为如果我们知道我们未能在可接受的时间内(如10秒)交付页面,我们不想让资源繁忙)。我们知道我们可以对SQL查询使用MySQL wait_timeout等设置,但页面超时将取决于执行的查询数量。

有些人试图想出变通办法,但似乎无法实施。

问:有没有一种简单的方法可以在linux上获得真正的PHP max_execution_time,或者我们在其他地方更好地计时,比如Apache级别

这是一个相当棘手的建议,但如果您愿意修改和重新编译PHP,它肯定会满足您的要求。

查看PHP源代码https://github.com/php/php-src/blob/master/Zend/zend_execute_API.c(文件是Zend/zend_execute_API.c),在函数zend_set_timeout处。这是实现时间限制的函数。以下是它在不同平台上的工作方式:

  • 在Windows上,创建一个新线程,启动一个计时器,当它完成时,将一个名为timed_out的全局变量设置为1,PHP执行核心会检查每个指令的该变量,然后退出(非常简化的)

  • 在Cygwin上,将itimer与itimer_REAL一起使用,后者测量实际时间,包括任何睡眠、等待等,然后发出信号,该信号将中断任何处理并停止处理

  • 在其他unix系统上,将itimer与itimer_PROF一起使用,后者只测量当前进程(但在用户模式和内核模式下)所花费的CPU时间。这意味着等待其他进程(比如MySQL)不算在内。

现在,您要做的是将Linux上的itimer从itimer_PROF更改为itimer_REAL,当然您需要手动执行、重新编译、安装等操作。这两者之间的另一个区别是,当计时器用完时,它们也使用不同的信号。所以我的建议是更改ifdef:

#   ifdef __CYGWIN__

进入

#   if 1

以便将ITIMER_REAL和PHP等待的信号都设置为SIGALRM。

不管怎么说,整个想法都是未经测试的(我将其用于一些非常特定的系统,ITIMER_PROF已损坏,并且似乎可以工作),不受支持,等等。使用它的风险自负。它可以与PHP本身一起工作,但它可能会破坏其他模块,在PHP和Apache中,如果它们出于任何原因,使用SIGALRM信号或其他计时器。

这是一个古老而有答案的问题。但为了帮助他人,我想指出request_terminate_timeoutphp-fpm选项。如果您正在使用PHP-FPM,它很可能是您所需要的。

如果设置了此选项,则可以告诉PHP-FPM在N秒后终止请求,而不管PHP做什么。

请参阅http://php.net/manual/en/install.fpm.configuration.php#request-有关详细信息,请终止超时。

来自httpd.conf:

超时:接收和发送超时前的秒数

超时300

最新更新