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

Тема в разделе "PHP", создана пользователем horpah, 24 мар 2011.

Модераторы: latteo
  1. horpah

    horpah

    Регистр.:
    21 июн 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-и сутки. Полет нормальный, память на месте.
     
  2. bork75

    bork75 The Team

    Регистр.:
    21 июн 2008
    Сообщения:
    1.450
    Симпатии:
    717
    Нужно всё проверять опытным путём, если на локалке не вырубает, значит таймаут браузера отметаем.

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

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

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

    т.е. возможны обрывы связи, нужно в скрипте сделать реконект.
     
  3. horpah

    horpah

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

    PS. за ночь 12 падений. Интервалы от 1,5 минут до неск часов.
     
  4. saen

    saen

    Регистр.:
    6 авг 2006
    Сообщения:
    756
    Симпатии:
    129
    Падать может сервер, но не скрипт. На каждый запуск по крону апач создает дочерний процесс(worker). Процесс либо завершается, либо не завершается. Тут надо смотреть логи апача и твой код полностью
     
  5. horpah

    horpah

    Регистр.:
    21 июн 2010
    Сообщения:
    199
    Симпатии:
    55
    Да, не так выразился. Падает процесс. В логах апача ничего, кроме ошибки отсутствующей картинки, определенной в CSS. Какие именно записи нужно искать?

    Код....
    Код в основном приведен 1 вопросе. В случае ошибки. даже незначительной - Errorhandler отработает, в случае естественного завершения работы (например по команде) - shutdown().
    Ошибок нет, лог чист. shutdown только по команде или нек. другим предусмотренным факторам.
     
  6. saen

    saen

    Регистр.:
    6 авг 2006
    Сообщения:
    756
    Симпатии:
    129
    Код приведен не в основном.
    PHP:
    if(already_running()) //проверка запущена ли копия.
      
    exit;
    while(
    true){ //основной цикл
      
    sleep($time);
      ........
      
    CODE
      
    ........
      
    check_commands(); //тут проверяются комманды скрипту
    }
    Вот этот кусок приведен для телепатов
     
  7. t0wer

    t0wer BlackHerald

    Регистр.:
    24 июн 2008
    Сообщения:
    733
    Симпатии:
    423
    Ну локальный сервер и удаленный я бы сравнивать на однородную работу не стал бы.
    Мне кажется что тут дело все-таки в скрипте и настройках сервера.
    Честно говоря не рекомендуется устанавливать на вечность работу скрипта
    PHP:
    set_time_limit(0);
    Может выбрать временной интервал и отследить когда выпадет фатальная ошибка на завершения скрипта и от нее плясать?
    set_time_limit() не действует, если PHP запущен в режиме safe mode. Нет иного выхода, кроме отключения safe mode или изменения лимита времени в файле конфигурации (тогда вступает в силу значение max_execution_time, определённое в файле конфигурации).
    Еще как вариант можно в промежуточные процедуры впихнуть отчет, чтобы знать на каком из этапов и в каком месте прошел СТОП! Если нет логов, то сто пудов это вальяжность программы. Да и сам скрипт коряво написал + запчастями тоже особо не погадаешь.
     
  8. pitkina

    pitkina

    Регистр.:
    1 апр 2007
    Сообщения:
    253
    Симпатии:
    176
    на шаредах(правильно настроенных) обычно запрещают оставлять процессы
    например на apache/mod_fastcgi за это отвечает опция killInterval, nginx закрывает процессы по своему таймеру, также иногда set_time_limit добавляют в disabled functions
    таким обр. set_time_limit(0) может быть полнофункционально только на своем сервере
     
  9. horpah

    horpah

    Регистр.:
    21 июн 2010
    Сообщения:
    199
    Симпатии:
    55
    Этот кусок телепетить и не надо :).
    PHP:
    set_error_handler('Errorhandler');  // обработчик ошибок 
    set_exception_handler('Errorhandler'); //обработчик исключений 
    register_shutdown_function('shutdown'); //завершающая функция
    И все ошибки любого уровня попадают в Errorhandler(), где пишутся в лог. Проверено и не в 1 проекте, что даже если допустить незначительные ошибки типа неинициализированного $i++; Еrrorhandler выпадает железно. И в нем пишется все это в лог. При завершении скрипта (по ошибке или естественно) также вываливается shutdown(). Ни того ни другого нет, следовательно убивают его без права на последнее слово.

    Написал, что время от нес. секунд (15 было минимум) до неск. часов. (11 часов 34 мин.55 сек был максимум). Перед этим скриптом в качестве тестового висел на сервере тестовый, он за 36 часов не упал, и я его руками прибил.
    Все протоколируется: время старта, тек. время и потребляемая память после каждого цикла (отсюда и знаю время работы). Утечек памяти нет.
     
  10. t0wer

    t0wer BlackHerald

    Регистр.:
    24 июн 2008
    Сообщения:
    733
    Симпатии:
    423
    Если у вас все так ровно и красиво, то по вашим словам вся проблема только в программе. Сравнивайте со своей тестовой. Отличительные функции нагружайте постепенно в тестовую и смотрите за процессом. Как только начнет падать при новой процедуре, то вот там как раз ваша проблема. В принципе больше добавить то и нечего, все и так перелопатили.