Как правильней обрабатывать PHP скрипт с временем выполнения в 5-10 минут?
Добрый день, подскажите советом насчет оптимизации работы долгих скриптов.
Суть задачи.
Внутри фреймворка есть скрипт, который занимается автоматическим обновлением некоторых данных у пользователя (скачивает csv файл по API, парсит и пишет в таблицу к каждому пользователю).
Система предполагает что у кого-то это файл будет размером в 5000 строк а у кого то в 20 000 строк.
Соответственно когда таких файлов 10+ то скрипт в 30 секунд не вкладывается, и хуже того может даже оборваться прям в процессе работы.
Нужен совет насчет оптимизации такой задачи. Крон сейчас не помогает, так как при обрыве приходится снова возвращаться к тому же файлу, и он снова "не влазит" в 30 сек.
Какие решения могут быть в принципе ?
Нужно ли использовать сервер очередей, решит ли это проблему ?
Или нужно работать из PCNTL библиотекой и перезапускать скрипт ?
P.S. Еще один фактор это то, что клиент сам указывает время обновления, например 17:00. Но если файлов на 17:00 будет 100 штук, то с кроном сейчас он обновление может получить и в 18 часов или не получить вообще
Станислав Тамат, Спасибо, но еще такой вопрос, действительно ли нужно ставить сервер очередей ? я никогда с ними не работал и сделать корректную оценку его надобности не могу, много читал видел явные плюсы. Но вот моя задача на самом деле заключается в том, что есть один скрипт, который будет работать круглосуточно с интервалом в 15 минут и проводить закачку файла по api и записывать данные оттуда в БД.
Переписать скрипт на cli версию получилось, он теперь не отваливается, а запускаю я его при помощи cron, просто вызываю в режиме cli.
Из всего этого, подскажите, такая организация работы нормальная или реально сервер очередей делает это лучше и главное надежней ?
Если выполнение процесса может оборваться в любой момент и вам нужно гарантировать его то я бы воспользовался очередями. Запаковываете часть вашего скрипта в консольную команду которую поставите на cron (ту часть которая отвечает за выборку пользователей для процессинга). Вторую часть, отвечающую за скачку файла по api и обновление юзера заворачиваете в консюмер на очереди. Таким образом сможете гарантировать что все ваши пользователи будут обработаны, а для тех что не завершились без ошибок (они вернутся в очередь) сможете добавить фикс для корректной их обработки.
Все ваши воркеры (консюмеры) ставите на supervisord. Чтобы один консюмер не надрывался над вашей кучей - указываете кол-во процессов в конфиге супервизора.
Для решения задачи со временем можно сделать 2мя способами:
1. Во время выборки на консольной команде засылать в очередь только тех пользователей кто должен сейчас обновиться
2. Для каждого сообщения проставляете поле время. На конюсмере проверяете это время, если рано то кидаете обратно в очередь