Real max_execution_time для PHP на Linux

Согласно документации:

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 секунд). Мы знаем, что мы можем играть с настройками, такими как MySQL wait_timeout для SQL-запросов, но таймаут страницы будет зависеть от количества выполненных запросов.

Некоторые люди пытались придумать обходные пути, и это не представляется возможным.

В: Есть ли простой способ получить реальный PHP max_execution_time в Linux, или лучше ли вам найти время в другом месте, например, уровень Apache ?

Related of "Real max_execution_time для PHP на Linux"

Это довольно сложный совет, но он обязательно сделает то, что вы хотите, если вы хотите изменить и перекомпилировать 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, который измеряет только время процессора, затрачиваемое на текущий процесс (но как в режиме пользователя, так и в режиме ядра). Это означает, что ожидания других процессов (например, MySQL) не учитываются.

Теперь вы хотите изменить itimer на вашем Linux с ITIMER_PROF на ITIMER_REAL, что, конечно же, вам нужно сделать вручную, перекомпилировать, установить и т. Д. Другая разница между этими двумя заключается в том, что они также используют разные сигналы при запуске таймера вне. Поэтому мое предложение – изменить ifdef:

 # ifdef __CYGWIN__ 

в

 # if 1 

так что вы устанавливаете ITIMER_REAL и сигнал, который PHP ожидает для SIGALRM.

Во всяком случае, вся эта идея непроверена (я использую ее для какой-то конкретной системы, где ITIMER_PROF разбит, и, похоже, работает), неподдерживается и т. Д. Используйте его на свой страх и риск. Он может работать с самим PHP, но он может сломать другие модули, в PHP и Apache, если они по какой-либо причине используют сигнал SIGALRM или другой таймер.

Это старый и ответивший вопрос. Но ради того, чтобы помогать другим, я хотел указать параметр request_terminate_timeout php-fpm. Если вы используете PHP-FPM, это скорее всего то, что вам нужно.

Если этот параметр установлен, этот параметр позволяет вам сообщить PHP-FPM, чтобы он убил запрос через N секунд, независимо от того, что делает PHP.

Подробнее см. http://php.net/manual/en/install.fpm.configuration.php#request-terminate-timeout .

Из httpd.conf:

Тайм-аут: количество секунд до приема и отправки тайм-аута

Таймаут 300