@thejohndoe

Как реализовать повторяющиеся задачи в php (cron)?

Здравствуйте! Направьте, пожалуйста, в правильное русло.

Есть 2 ситуации, которые необходимо решить с использованием php.

1. Воспроизведение функции в четко определенное время. Наглядный пример - пользователь создает напоминание на определенную дату и время (например, на сегодня, 22:35) и ровно в это время должен отработать скрипт (в данном случае, к примеру, отправить уведомление на почту).

Как реализовать это наиболее грамотно? Настроить по cron с промежутком в 1 минуту скрипт, который будет проверять наличие каких-либо заданий на текущую минуту? Это будет наиболее верным решением? Как быть, если выполнение функции требует времени (к примеру, речь о парсинге), и в определенное время нужно выполнить несколько заданий одновременно? К примеру, критически важно спарсить данные из трех источников минуту в минуту.

Я говорю о том, что если реализовать это в порядке очереди, то следующая итерация функции произойдет только после окончания предыдущей. Т.е. пока скрипт не спарсит первые данные, к парсингу вторых он не перейдет.

Читал о многопоточности в curl, т.е. на случай парсинга решение есть, но как быть в других ситуациях?

2. Реализация повторения функции. Пример - пользователь запускает задание, в рамках которого одна и та же функция должна выполниться на сервере, например, 100 раз с интервалом в 40 секунд. Как это реализовать наиболее грамотно?

Основная проблема тут именно во времени выполнения скрипта. Я знаю про set_time_limit / max_execution_time, но единственное ли это решение? И вообще насколько правильно, например, отключать максимальное время выполнения скрипта, если мы не знаем, сколько это может занять времени?

Вопросы скорее не о конкретных примерах, т.е. функция может быть любой - отправка почты, обращение к api, парсинг данных и проч. Интересно именно то, как правильно это реализовать. Подскажите, куда рыть, что читать.

Спасибо.
  • Вопрос задан
  • 499 просмотров
Пригласить эксперта
Ответы на вопрос 2
DaFive
@DaFive
Есть реализации крона (не сам по себе crontab, а на баше том же) и раз в секунду, можно нагуглить варианты.
Можно использовать сервер очередей (к примеру Gearman). Сервер выполняет задачу и имеет о ней все данные. Задачу можно перепоставить себе же автоматически после выполнения, попутно изменив у нее определенные данные.

Спарсить 3 задачи - тоже легко. Делаются для этого же сервера 3 воркера, которые работают параллельно. Как только гирману поступает задача, свободный воркер её сразу хватает. Поступят 3 задачи - 3 воркера их расхватают и будут выполнять одновременно. Причем для задач можно выставить приоритеты. Необязательные пускать с low, обязательные с high приоритетом. Свободный воркер решит какую задачу брать сам.

Вообще промежуточные данные при запуске скрипта (таймауты и прочее) можно хранить любым nosql решением. Хоть в файл пишите, хоть в redis, хоть в memcache, если обращение к базе некритично. Статусы завершенности задач, типы задач, задачи, которые исполняются - все там же. Ну или опять же в базе. Тут как удобнее.

Раньше, к примеру, мы постраничный парсинг реализовывали через redis. Крон запускался раз в 10 минут (долго парсилось), и в редис клалось значение текущей страницы. При последующем запуске скрипта значение доставалось и по нему отлистывалась следующая страница при запросе к API. Потом этот ключ грохали (уже не вспомню, либо вручную либо по expire) и все начиналось заново.
Ответ написан
Комментировать
@mickvav
Programmer, system and network administrator
Я бы делал небольшого отдельного демона/скрипт/whatever, который стартует из-под крона с какой-то частотой, проверяет блокировку (flock-ом, на крайняк), лезет в базу, понимает, какие ему сейчас надо выполнить задачки, запускает child-процессы для их обработки (тут можно и аппетиты ограничить, если надо), отмечает в базе, что процессы запущены, освобождает блокировку и мрёт. Это если погрешность в одну минуту - не смущает.

Если смущает - отдельный демон, который слушает, например, сигналы ОС, и по прибытию сигнала от php-приложения или своего собственного аларма, проделывает вот это всё из первого абзаца, только сперва отключив обработку сигналов ;). При стартек демон пишет свой pid куда-нибудь, чтобы ваше приложение знало, кому сигналить. ;)
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы