PHP: запуск задачи в фоне

Какие самые правильные и надежные подходы стоит использовать, если необходимо запустить некую длительную задачу в фоновом режиме?
Приведу пример, чтобы стало понятней:
есть основной php скрипт, контроллер, который обрабатывает пользовательские действия. Пользователь нажимает в интерфейсе волшебную кнопку, которая должна запустить долгоиграющую задачу и вернуть управление пользователю. При этом не требуется возвращать или как то дополнительно обрабатывать результат работы длительного скрипта.

Знаю, что для подобных задач существуют различные библиотеки для создания очереди сообщений, но конкретно для моего примера это избыточно.
Так же хотелось бы обойтись без cron-task-ов и других ОС-специфичных вещей.

Спасибо.
  • Вопрос задан
  • 24963 просмотра
Решения вопроса 1
WebSpider
@WebSpider
По-моему, в вашем случае самым простым вариантом будет exec:

exec("php /www/site/script.php >>/www/logs/script.log 2>&1 &");

К сожалению это будет работать только в *nix, потому что в Windows запустить процесс в фоне не так то просто
Ответ написан
Пригласить эксперта
Ответы на вопрос 5
@Jazzist
PHP CLI в фоне ведет себя плохо. Из того, что применяется «на скорую руку», хорошо себя ведут BASH, Perl и Python.

В задаче, где надо было беречь ресурсы, поступил так:
1. Скрипт на PHP сохраняет «задание» на BASH в некоторую директорию job
2. Крон ежеминутно запускает некий скрипт dispatcher, написанный на Perl (был жизнеспособный вариант и на BASH) который ищет N самых старых (по last modified time) скриптов из директории job, и запускает их.
3. Запускаемые скрипты первым делом уничтожают (rm) себя, чтобы не Они все равно выполнятся — ведь они уже загружены в ОЗУ. Результаты работы сохраняются в ФС или в БД, для обслуживания логики интерфейса

Число N для каждого конкретного сервера выявляется индивидуально — тестированием.

Был «подводный камень», который по первому разу даже был обнаружен совершенно невовремя — все, что запускает крон, должно работать с абсолютными путями.

Таким образом были сделаны проект вроде ютуба и аналогичный, тоже конвертирующий видео.
Ответ написан
StraNNikk
@StraNNikk
Я тоже придерживаюсь варианта с CRON-ом.
Лично я бы складывал бы задачи в таблицу в БД, где фиксировались бы статусы выполнения задач, а в кроне ежеминутно отрабатывал бы некий скрипт (хоть на php хоть на чем другом), который бы чекал эту таблицу, запускал новые задачи, и удалял уже отработанные.
Ответ написан
molodoy
@molodoy
Как вариант: пользователь нажимает кнопку — ajax-запросом на сервере запускается php-скрипт (с ignore_user_abort).
Ответ написан
Комментировать
eternals
@eternals
1. Агенты — запускают в конце генерации страницы.
Ответ написан
@Super0leg
<?php
 
ob_start(); // включаем буферизацию вывода
session_start(); // стартуем сессию(если нужна)
 
/* тут некий код наш */
 
echo 'Goodbye my friend!'; // пишем нечто в буфер
 
session_write_close(); // записываем сессию с сохранением
set_time_limit(0); // делаем лимит времени выполнения бесконечным(не обязательно)
ignore_user_abort(true); // игнорим что клиент отвалился и продолжаем работу
header('Connection: close'); // посылаем заголовок клиенту, чтобы он отвалился
header('Content-Length: ' . ob_get_length()); // посылаем количество байт
ob_end_flush(); // сбрасываем самый верхний буфер вывода
flush(); // сбрасываем системный буфер и отправляем
fastcgi_finish_request(); // сброс данных запроса клиенту(в случае php-fpm необходимо!)
 
/*
тут некий дальнейший код, он продолжит выполнение уже после закрытия связи с клиентом
*/


Источник - https://itnots.ru/php/asinhronnost-v-php-otdat-otv...
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы