Преждевременное завершение задания 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
Настройка конфигурации, потому что:
- Я точно знаю, что он работал в течение 29:18 минут (то есть намного больше, чем 60-е годы, как сообщение об ошибке).
- Из документов 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