ФорумПрограммированиеPHP для идиотов → Как правильно запустить фоновый скрипт на сервере (если это возможно)

Как правильно запустить фоновый скрипт на сервере (если это возможно)

  • Cheese

    Сообщения: 74 Репутация: N Группа: Кто попало

    Spritz 14 октября 2008 г. 23:54

    Правильно заданный вопрос это половина ответа(причем большая половина). Но поиску я по своей беде правильный вопрос задать так и не смог и вынужден попробовать спросить так…

    Итак:
    Со страницы стартует по ссылке большой и тяжелый скрипт(выполняется 3-15 минут) результат выполнения этого скрипта высылается пользователю на мыло. Как избавить пользователя от необходимости смотреть четверть часа на белый квадрат недоумевая что жетам все-таки происходит? Т.е. нужно стартовать на сервере скрипт сказать пользователю что скрипт стартовал и отпустить пользователя с миром(вплоть до закрытия им браузера)… pcntl_fork() - я так понимаю, тут не поможет так как при закрытии родителя ребенок сгинет тоже(или я не прав?) Что еще остается?

    Беда моя еще и в том что на локали под виндой это дело смоделировать не выходит(того же форка в винде нету) а на сервере у хостера "шалить" не хочется…
  • AlexB

    Сообщения: 4306 Репутация: N Группа: в ухо

    Spritz 15 октября 2008 г. 1:00, спустя 1 час 6 минут 9 секунд

    Положить заявку пользователя в базу и уведомить, что она принята.

    По крону регулярно стартовать скрипт, который берет невыполненную заявку, просчитывает, отправляет результат, помечает заявку как выполненную.
  • Cheese

    Сообщения: 74 Репутация: N Группа: Кто попало

    Spritz 15 октября 2008 г. 1:39, спустя 38 минут 55 секунд

    AlexB, спасибо… идея очень вкусная…. с кроновыми скриптами как-то пока не сталкивался, но думаю что осилю… Еще раз спасибо

  • Trej Gun

    Сообщения: 5305 Репутация: N Группа: в ухо

    Spritz 15 октября 2008 г. 10:05, спустя 8 часов 26 минут 3 секунды

    Cheese, у пхп есть параметр который продолжит выполнять скрипт после закрытия окна браузера
  • Cheese

    Сообщения: 74 Репутация: N Группа: Кто попало

    Spritz 15 октября 2008 г. 11:58, спустя 1 час 52 минуты 58 секунд


    Cheese, у пхп есть параметр который продолжит выполнять скрипт после закрытия окна браузера

    А можно с этого места по-подробнее?
    Т.е. юзер запустил по ссылке скрипт, с помощью какого-нибудь flush() скрипт выдал юзеру предложение идти на все четыре стороны со сцылкой на страницу с которой он скрипт запустил и при этом уход юзера не остановит выполнение скрипта? Если я понял правильно то намекните плиз как это сделать?
  • Trej Gun

    Сообщения: 5305 Репутация: N Группа: в ухо

    Spritz 15 октября 2008 г. 12:26, спустя 28 минут 39 секунд

    при этом уход юзера не остановит выполнение скрипта?

    именно так

    поищи в php.ini
  • AlexB

    Сообщения: 4306 Репутация: N Группа: в ухо

    Spritz 15 октября 2008 г. 12:51, спустя 24 минуты 15 секунд


    Т.е. юзер запустил по ссылке скрипт, с помощью какого-нибудь flush() скрипт выдал юзеру предложение идти на все четыре стороны со сцылкой на страницу с которой он скрипт запустил и при этом уход юзера не остановит выполнение скрипта
    Ага … а потом скрипт отваливается по таймауту или двадцать юзеров одновременно запускают такие скрипты и сервер валится от нагрузки … короче заявки остаются необработанными …
  • Trej Gun

    Сообщения: 5305 Репутация: N Группа: в ухо

    Spritz 15 октября 2008 г. 13:11, спустя 20 минут 24 секунды

    AlexB, с таймаутом тоже можно бороться при помощи того же php.ini
    а вот нагрузка на сервер это да))) тут ты прав
  • Cheese

    Сообщения: 74 Репутация: N Группа: Кто попало

    Spritz 15 октября 2008 г. 13:12, спустя 1 минуту

    … короче заявки остаются необработанными …

    Ну риск наплодить монстров при таком подходе безусловно есть…
    А как поведет себя кроновый скрипт если время его выполнения будет превышать интервал запуска. Допустим, скрипт идет раз в час, в базе за час пять заявок,
    скрипт ушел считать на часа на полтора…
    Возникают два вопроса:
    1. Он за полтора часа по таймауту не пристрелится?
    2. Что произойдет через час? Запустится второй экземпляр? А если в базе будут еще новые заявки пойдет еще один расчет?

    поищи в php.ini

    беглый просмотр результатов не дал…
  • Cheese

    Сообщения: 74 Репутация: N Группа: Кто попало

    Spritz 15 октября 2008 г. 13:16, спустя 3 минуты 36 секунд


    а вот нагрузка на сервер это да))) тут ты прав


    Нагрузки можно избежать заставив каждый живой экземпляр региться в базе и не давать стартовать новому если экземпляров много…
  • AlexB

    Сообщения: 4306 Репутация: N Группа: в ухо

    Spritz 15 октября 2008 г. 14:11, спустя 55 минут 51 секунду


    1. Он за полтора часа по таймауту не пристрелится?

    Скрипты запускаемые через CLI по умолчанию не имеют таймаута.


    2. Что произойдет через час? Запустится второй экземпляр? А если в базе будут еще новые заявки пойдет еще один расчет?

    Да, пойдет еще один расчет.

    Но видишь ли, тут уже вопрос что за страшные расчеты ты собрался делать? Ты задаешь модель, когда заявки поступают быстрее, чем обрабатываются сервером. Тут как не реализуй, сервер рано или поздно упадет, ибо нагрузка стремится к бесконечности.

    Можно уйти от нагрузки, сделав у заявки три статуса - ожидает, обрабатывается, обработана и не запускать новую обработку, пока есть хоть одна заявка со статусом "обрабатывается". Но опять же, в таком случае время ожидания клиентом обработки стремится к бесконечности.

    Т.е. тут надо уже думать не об способах реализации, а об оптимизации алгоритма расчета, увеличение серверных мощностей и.т.д.


  • Cheese

    Сообщения: 74 Репутация: N Группа: Кто попало

    Spritz 16 октября 2008 г. 11:19, спустя 21 час 7 минут 41 секунду

    Вариант решения к которому я склоняюсь после краткого курения манов таков:

    Начинаем стартовать монстроскрипт c ignore_user_abort(true) и set_time_limit(1800) проверяем заданную директорию на наличие файлов-флагов если файлов-флагов есть 5(т.е. уже идет пять расчетов) то говорим пользователю подождать 10 минут и заканчиваем скрипт, иначе создаем новый файл-флаг. С помощью flush() ob_flush() говорим пользователю что ему можно идти своей дорогой давая ссылку на страницу с которой расчет запущен. Выполняем расчет. Убиваем флаг-файл. Отсылаем результат.

    Просьба к желающим покритиковать этот вариант.
  • md5

    Сообщения: 11960 Репутация: N Группа: в ухо

    Spritz 16 октября 2008 г. 11:32, спустя 12 минут 35 секунд

    Cheese, вы раньше не писали на скриптовых языках?
    все умрут, а я изумруд
  • Trej Gun

    Сообщения: 5305 Репутация: N Группа: в ухо

    Spritz 16 октября 2008 г. 11:42, спустя 10 минут 19 секунд

    Cheese, мд5 намекает что флагфайлы отстой в данных условиях
  • Cheese

    Сообщения: 74 Репутация: N Группа: Кто попало

    Spritz 16 октября 2008 г. 11:55, спустя 12 минут 39 секунд


    Cheese, мд5 намекает что флагфайлы отстой в данных условиях

    Намек понял :)
    А почему, если не секрет?
    Если заменить флаг-файл на запись в БД что-то радикально изменится…


    PS Умом понимаю, что вариант с кроном лучше но почему-то его так не хочется… даже не знаю…

Пожалуйста, авторизуйтесь, чтобы написать комментарий!