Преждевременное завершение задания PHP cron из-за фатальной ошибки "Максимальное время выполнения"

У меня есть задание PHP cron, которое не работает после 29 минут работы. Ошибка в журнале (/var/log/php_errors.log) является:

[01-Mar-2012 00:32:57 UTC] PHP Fatal error: Maximum execution time of 60 seconds exceeded in /path/file.php on line 2079

Запись в crontab, которая запускает cron:

00 00 * * * /usr/bin/php /path/file.php

Из моего исследования я не думаю, что это связано с max_execution_time Настройка конфигурации, потому что:

  1. Я точно знаю, что он работал в течение 29:18 минут (то есть намного больше, чем 60-е годы, как сообщение об ошибке).
  2. Из документов PHP - при запуске PHP из командной строки значение по умолчанию равно 0.

Q: Почему сценарий заканчивается рано?


Заметки:

Сценарий очень тяжелый и выполняет много тысяч запросов к БД, но я выполнял top и загрузка процессора не была высокой.

Строка из журнала ошибок является mysql_query вызов:

$sql = "SELECT SUM(amount) FROM mytab WHERE mem = '$id' AND validto > '$now'";
$res = mysql_query($sql);

> php -v
PHP 5.3.10 (cli) (built: Feb  2 2012 17:34:38) 
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies
    with Suhosin v0.9.33, Copyright (c) 2007-2012, by SektionEins GmbH

> cat /etc/redhat-release
Red Hat Enterprise Linux Server release 5.7 (Tikanga)

Обновление - я выяснил, почему скрипт может работать в течение 29 минут в режиме реального времени, но PHP может значительно сократить время выполнения цитирования.

Любое время, потраченное на действия, которые происходят за пределами выполнения сценария, такие как системные вызовы с использованием system(), потоковые операции, запросы к базе данных и т. Д., Не учитывается при определении максимального времени выполнения сценария.

(из документации set_time_limit(), но также упоминается в документации по максимальному времени выполнения). Это было актуально для меня, потому что большая часть скрипта долго выполняла дБ-запросы и платежные API-вызовы, которые не будут увеличивать время выполнения.

3 ответа

Решение

Если вы получаете PHP Fatal error: Maximum execution time of 60 seconds exceeded тогда наверняка какой-то кусок бегущего PHP-кода выполняет оператор set_time_limit(60) где-то. Режим PHP CLI может по умолчанию не ограничивать время, но если какой-либо путь к коду когда-либо устанавливает ограничение по времени, он будет соблюден. Причина, по которой PHP работал почти полчаса, заключается в том, что set_time_limit устанавливает ограничение для времени ЦП, и если процесс ограничен вводом-выводом или ожидает других процессов, общее использование ЦП достигнет отметки 60 секунд намного позже в часах реального времени.

Попробуйте найти весь ваш исходный код для set_time_limit, Если вы ничего не нашли, то добавьте set_time_limit(0) в начале скрипта, чтобы убедиться, что ограничение 60 секунд не исходит из локально модифицированного файла конфигурации. Например, в Ubuntu LTS конфигурация CLI PHP определяется в /etc/php5/cli/php.ini,

Ну, вы можете установить большее значение для ограничения по времени, или вы можете установить его неограниченным, используя set-time-limit ():

<?php set_time_limit(0); ?>

но на самом деле я использую это тоже в начале сценария

ignore_user_abort(1);

К сожалению, я не могу написать комментарий, поэтому мой вопрос здесь будет, что произойдет, если вы запустите это вручную? Будет ли это также время ожидания?

Если он не истекает, когда вы запускаете его вручную, я бы посоветовал вам вызвать небольшой сценарий оболочки, который фактически запускает оболочку и запускает "/usr/bin/php /path/file.php" внутри оболочки.

00 00 * * * /usr/local/scripts/start_php_job.sh

File: /usr/local/scripts/start_php_job.sh
#!/usr/bin/bash
date

/usr/local/bin/php /path/to/script

date
Другие вопросы по тегам