Задача Cron для скрипта php, требующая ОЧЕНЬ долгого времени выполнения

У меня есть php-скрипт, выполняемый как задание cron, которое выполняет набор простых задач, которые петли для каждого пользователя в базе данных и занимают около 30 минут. Этот процесс начинается каждый час и должен быть максимально быстрым и эффективным. Проблема Im, похожая на любой серверный скрипт, время выполнения варьируется, и мне нужно выяснить лучшие временные настройки cron.

Если я запускаю cron каждую минуту, мне нужно остановить последний цикл скрипта за 20 секунд до конца минуты, чтобы убедиться, что текущий цикл заканчивается во времени. В течение часа это добавляет много времени впустую.

Im интересно, если его плохая идея, чтобы просто удалить ограничение времени выполнения php и запустить скрипт один раз в час и позволить ему работать до завершения …. это плохая идея?

Solutions Collecting From Web of "Задача Cron для скрипта php, требующая ОЧЕНЬ долгого времени выполнения"

Предполагая, что вы хотите выполнить работу как можно скорее, не используйте cron. Cron хорош для вещей, которые должны произойти в определенное время. Часто злоупотребляют имитировать фоновый процесс, который идеально подходит для работы, как только появится работа. Вероятно, вы должны написать демона, который работает непрерывно. (Примечание: вы также можете посмотреть систему типа «сообщение / работа-очередь», там есть интересные библиотеки)

Вы можете написать демона с нуля с помощью функций pcntl (так как вы не заботитесь о нескольких рабочих процессах, очень легко получить процесс, выполняющийся в фоновом режиме.), Или обмануть и просто создать скрипт, который выполняется навсегда и запускать это через экран или использовать какой-то твердый библиотечный код, такой как система PEAR : Daemon или nanoserv

Как только материал демонанизации позаботится, все, что вам действительно нужно, это цикл, который работает навсегда. Вы захотите позаботиться о том, чтобы ваш скрипт не просачивал память или не потреблял слишком много ресурсов.

Как правило, вы можете сделать что-то вроде:

<?PHP // some setup code while(true){ $todo = figureOutIfIHaveWorkToDo(); foreach($todo as $something){ //do stuff with $something //remember to clean up resources so you don't leak memory! usleep(/*some integer*/); } usleep(/* some other integer */); } 

И все будет хорошо.

Вместо установки max_execution_time вы также можете использовать set_time_limit () для сброса счетчика в каждом цикле. Это гарантирует, что ваш скрипт никогда не истечет времени, если в текущем цикле (и занимает больше времени max_execution_time) не будет чего-то серьезного.

В основном это должно заставить ваш скрипт работать столько, сколько ему нужно, давая ему 30-секундный тайм-аут между двумя вызовами set_time_limit() .

Установка лимита времени 0 и позволяющая ему делать это довольно типично для PHP-cronjobs (по моему опыту), но это также вопрос, когда вы должны задать себе несколько важных вопросов, таких как «Должен ли я переписать эту работу в скомпилированный язык? " и «Я использую все свои инструменты (базу данных и т. д.) до максимальной эффективности?»

Тем не менее, возможно, лучше, чем полностью удалить ограничение по времени, было бы установить его на верхний предел, который вы действительно хотите. Если это означает 48 минут, то set_time_limit(48 * 60);

Я действительно думаю, что вы не должны устанавливать время до 0, это просто ищет проблемы. В большинстве случаев установите его в 59 * 60 секунд, но установка его на 0 может вызвать проблемы с безопасностью, если скрипт зависает, он будет вешать почти навсегда, пока серверный сервер не остановит выполнение. Это считается плохой практикой.

В прошлом я использовал интерфейс командной строки php для аналогичных длительных задач. Вероятно, вы не хотите удалять ограничение времени выполнения для любого запроса.

Похоже на отличную идею, если мало шансов, что потребуется больше часа. Обратите внимание, однако, что неправильная ошибка может быть действительно хорошим способом заставить ее заняться дольше, чем ожидалось.

Чтобы избежать всех неприятных проблем, у вас должен быть файл защиты с идентификатором процесса скрипта. При запуске вы должны убедиться, что файл не существует, или если он делает, что идентификатор процесса в файле не существует (посредством вызова kill (pid, 0)). Если эти условия выполнены, создайте новый файл с PID сценария и удалите файл, когда закончите.

Это тот самый трюк, который используют многие демоны, чтобы убедиться, что он еще не запущен. Если демон внезапно был убит, файл все равно будет существовать, но PID процесса в нем вряд ли будет запущен.

В зависимости от того, что делает ваш скрипт, это может привести к проблемам, если вы удалите ограничение по времени. Если в примере вы опросили внешний сервер, который не отвечает на запросы во время выполнения задания, а ваш cron занимает 2 часа вместо 30 минут, вы можете получить стек процессов PHP, которые будут запущены, даже если предыдущие Еще не завершено. Это может привести к нестабильности системы и сбоям.

Вероятно, у вас есть два варианта:

  • Убедитесь, что другой экземпляр вашего скрипта не запущен заранее, иначе exit () при запуске.
  • Подумайте об изменении вашей кроны в демоне.

Должен ли он работать по часам, как часы?

Если не расколоть работу (вы упомянули, что это была более чем одна простая задача), выполняйте каждую задачу каждый час?

Или разделите его на пользователя, сделайте AM в час, затем NZ на следующий?