Прерывается PHP скрипт

horpah

Гуру форума
Регистрация
20 Июн 2010
Сообщения
199
Реакции
55
Есть PHP скрипт, в общем виде такой:
PHP:
set_time_limit(0);
ignore_user_abort(1);
set_error_handler('Errorhandler');  // обработчик ошибок
set_exception_handler('Errorhandler'); //обработчик исключений
register_shutdown_function('shutdown'); //завершающая функция
.........
if(already_running()) //проверка запущена ли копия.
  exit;
while(true){ //основной цикл
  sleep($time);
  ........
  CODE
  ........
  check_commands(); //тут проверяются комманды скрипту
}
function Errorhandler($type,$err,$file,$line) //обработчик ошибок
{
  записать все в лог ошибок
}
function shutdown() //завершение работы
{
  записать в лог время начала работы,
  время окончания работы 
  время выполнения, 
  память и пр. отчеты.
}

Цель - фоновая задача. Стартует ежеминутно кроном. Замечено, что на хостинге за сутки серипт "упал" 8 раз. Скрипт при старте и в основном цикле пишет текущее время, поэтому легко проследить сколько он продержался.
Минимальное время работы - менее 2-х минут. Максимальное - более 6 часов (работает до сих пор).
Хотелось бы узнать, чем могут быть вызваны такие падения. Команд на прерывание не поступало, логи ошибок и выходной пусты. Т.е. ошибок типа error и warning не было, естественного завершения тоже. Памяти утечки нет (1.01 мб на протяжении всего времени выполнения).
На локалхосте как браузером запустил, так он трудится уже 3-и сутки. Полет нормальный, память на месте.
 
Нужно всё проверять опытным путём, если на локалке не вырубает, значит таймаут браузера отметаем.

Дальше остаётся ограничения в php.ini с них и нужно начинать, ну и сам апач имеет timeout в httpd.conf.

Для начала сохранить оригинал php.ini, а потом всё менять.
В php.ini добавить времени на выполнение скрипта и памяти
max_execution_time
set_time_limit

Вообще обратить внимание на все значения с суфиксом limit, time, max кроме указанных выше, там есть и другие.

Документация к веб серверу apache гласит следующее:
Директива TimeOut в настоящее время определяет количество времени, которое Apache будет ожидать три вещи:
1. Время приема GET запроса.
2. Количество времени между получением TCP пакетов на POST или PUT запросе.
3. Количество времени между ACK на передачах TCP пакетов в ответах.
То есть таймаут веб сервера может срабатывать как правило в случае наличия проблем с сетью, невозможности доставки пакетов от сервера к клиенту и так далее

т.е. возможны обрывы связи, нужно в скрипте сделать реконект.
 
в php.ini max_execution_time стандартно - 30 сек.
Время я выставляю в самом скрипте, благо хостинг позволяет.
PHP:
set_time_limit(0); 
ignore_user_abort(1);
По поводу Апача и таймаута не совсем понял при чем они тут. Скрипт стартует кроном, хотя можно стартовать и браузером. Если бы вступали какие-то временные ограничения - скрипт бы падал с одинаковыми временными интервалами. На ночь поставил логгирование времени выполнения главного цикла. Максимальное значение стабильно и не превышало единиц мс.

PS. за ночь 12 падений. Интервалы от 1,5 минут до неск часов.
 
в php.ini max_execution_time стандартно - 30 сек.
Время я выставляю в самом скрипте, благо хостинг позволяет.
PHP:
set_time_limit(0); 
ignore_user_abort(1);
По поводу Апача и таймаута не совсем понял при чем они тут. Скрипт стартует кроном, хотя можно стартовать и браузером. Если бы вступали какие-то временные ограничения - скрипт бы падал с одинаковыми временными интервалами. На ночь поставил логгирование времени выполнения главного цикла. Максимальное значение стабильно и не превышало единиц мс.

PS. за ночь 12 падений. Интервалы от 1,5 минут до неск часов.
Падать может сервер, но не скрипт. На каждый запуск по крону апач создает дочерний процесс(worker). Процесс либо завершается, либо не завершается. Тут надо смотреть логи апача и твой код полностью
 
Падать может сервер, но не скрипт. На каждый запуск по крону апач создает дочерний процесс(worker). Процесс либо завершается, либо не завершается. Тут надо смотреть логи апача и твой код полностью
Да, не так выразился. Падает процесс. В логах апача ничего, кроме ошибки отсутствующей картинки, определенной в CSS. Какие именно записи нужно искать?

Код....
Код в основном приведен 1 вопросе. В случае ошибки. даже незначительной - Errorhandler отработает, в случае естественного завершения работы (например по команде) - shutdown().
Ошибок нет, лог чист. shutdown только по команде или нек. другим предусмотренным факторам.
 
Да, не так выразился. Падает процесс. В логах апача ничего, кроме ошибки отсутствующей картинки, определенной в CSS. Какие именно записи нужно искать?

Код....
Код в основном приведен 1 вопросе. В случае ошибки. даже незначительной - Errorhandler отработает, в случае естественного завершения работы (например по команде) - shutdown().
Ошибок нет, лог чист. shutdown только по команде или нек. другим предусмотренным факторам.
Код приведен не в основном.
PHP:
if(already_running()) //проверка запущена ли копия.
  exit;
while(true){ //основной цикл
  sleep($time);
  ........
  CODE
  ........
  check_commands(); //тут проверяются комманды скрипту
}
Вот этот кусок приведен для телепатов
 
Ну локальный сервер и удаленный я бы сравнивать на однородную работу не стал бы.
Мне кажется что тут дело все-таки в скрипте и настройках сервера.
Честно говоря не рекомендуется устанавливать на вечность работу скрипта
PHP:
set_time_limit(0);
Может выбрать временной интервал и отследить когда выпадет фатальная ошибка на завершения скрипта и от нее плясать?
set_time_limit() не действует, если PHP запущен в режиме safe mode. Нет иного выхода, кроме отключения safe mode или изменения лимита времени в файле конфигурации (тогда вступает в силу значение max_execution_time, определённое в файле конфигурации).
Еще как вариант можно в промежуточные процедуры впихнуть отчет, чтобы знать на каком из этапов и в каком месте прошел СТОП! Если нет логов, то сто пудов это вальяжность программы. Да и сам скрипт коряво написал + запчастями тоже особо не погадаешь.
 
на шаредах(правильно настроенных) обычно запрещают оставлять процессы
например на apache/mod_fastcgi за это отвечает опция killInterval, nginx закрывает процессы по своему таймеру, также иногда set_time_limit добавляют в disabled functions
таким обр. set_time_limit(0) может быть полнофункционально только на своем сервере
 
Вот этот кусок приведен для телепатов
Этот кусок телепетить и не надо :).
PHP:
set_error_handler('Errorhandler');  // обработчик ошибок 
set_exception_handler('Errorhandler'); //обработчик исключений 
register_shutdown_function('shutdown'); //завершающая функция
И все ошибки любого уровня попадают в Errorhandler(), где пишутся в лог. Проверено и не в 1 проекте, что даже если допустить незначительные ошибки типа неинициализированного $i++; Еrrorhandler выпадает железно. И в нем пишется все это в лог. При завершении скрипта (по ошибке или естественно) также вываливается shutdown(). Ни того ни другого нет, следовательно убивают его без права на последнее слово.

....
Может выбрать временной интервал и отследить когда выпадет фатальная ошибка на завершения скрипта и от нее плясать?
set_time_limit() не действует, если PHP запущен в режиме safe mode. Нет иного выхода, кроме отключения safe mode или изменения лимита времени в файле конфигурации (тогда вступает в силу значение max_execution_time, определённое в файле конфигурации).
Написал, что время от нес. секунд (15 было минимум) до неск. часов. (11 часов 34 мин.55 сек был максимум). Перед этим скриптом в качестве тестового висел на сервере тестовый, он за 36 часов не упал, и я его руками прибил.
Все протоколируется: время старта, тек. время и потребляемая память после каждого цикла (отсюда и знаю время работы). Утечек памяти нет.
 
Перед этим скриптом в качестве тестового висел на сервере тестовый, он за 36 часов не упал, и я его руками прибил.
Все протоколируется: время старта, тек. время и потребляемая память после каждого цикла (отсюда и знаю время работы). Утечек памяти нет.
Если у вас все так ровно и красиво, то по вашим словам вся проблема только в программе. Сравнивайте со своей тестовой. Отличительные функции нагружайте постепенно в тестовую и смотрите за процессом. Как только начнет падать при новой процедуре, то вот там как раз ваша проблема. В принципе больше добавить то и нечего, все и так перелопатили.
 
Назад
Сверху