【问题标题】:Real max_execution_time for PHP on linuxlinux 上 PHP 的真正 max_execution_time
【发布时间】:2012-04-19 00:48:28
【问题描述】:

According to the documentation:

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 之类的设置,但页面超时将取决于执行的查询数量。

有人尝试提出workarounds,但似乎无法实现。

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

【问题讨论】:

    标签: php mysql apache ubuntu timeout


    【解决方案1】:

    这是一个相当棘手的建议,但如果你愿意修改和重新编译 PHP,它肯定会做你想做的事。

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

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

    • 在 Cygwin 上,使用带有 ITIMER_REAL 的 itimer,它测量 实时 时间,包括任何睡眠、等待等,然后发出一个 信号 将中断 任何处理和停止处理

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

    现在你要做的是将你Linux上的定时器从ITIMER_PROF更改为ITIMER_REAL,这当然需要你手动完成,重新编译,安装等。这两者之间的另一个区别是它们也使用不同的信号时计时器用完。所以我的建议是改变 ifdef:

    #   ifdef __CYGWIN__
    

    进入

    #   if 1
    

    这样您就可以将 ITIMER_REAL 和 PHP 等待的信号都设置为 SIGALRM。

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

    【讨论】:

      【解决方案2】:

      这是一个古老且已回答的问题。但是为了帮助别人,我想指出request_terminate_timeout php-fpm 选项。如果您使用的是 PHP-FPM,那么它很可能是您所需要的。

      如果设置,此选项允许您告诉 PHP-FPM 在 N 秒后终止请求,无论 PHP 做什么。

      详情请参阅http://php.net/manual/en/install.fpm.configuration.php#request-terminate-timeout

      【讨论】:

        【解决方案3】:

        来自 httpd.conf:

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

        超时 300

        【讨论】:

        • 这不会影响 PHP 处理
        • 确实,我已经将 Apache TimeOut 设置为 2(秒)进行了测试,但它没有任何效果。除了mod_reqtimeout,还有什么可以推荐 John 的吗?
        猜你喜欢
        • 2013-03-24
        • 2014-10-11
        • 2021-04-02
        • 1970-01-01
        • 2012-02-03
        • 2012-06-30
        • 2011-05-12
        • 1970-01-01
        • 2012-07-02
        相关资源
        最近更新 更多