Запуск PHP-скрипта каждые 5 минут и избежание условий гонки

У меня есть PHP-скрипт, который нужно запускать каждые 5 минут. В настоящее время я использую задание cron для его запуска (и оно отлично работает), но мой хост допускает минимальное время в 15 минут.

Поэтому мой вопрос: могу ли я использовать посетителей для запуска запуска php-скрипта каждые 5 минут. Я могу просто просто записать последний раз, когда он запускался, и повторно запустить его на основе прошедшего времени.

Однако меня беспокоят условия гонки. Важно, чтобы скрипт запускался только раз в 5 минут.

Мой скрипт занимает около 60 секунд. За это время он пишет пару файлов. Если скрипт запускался более одного раза, это искажало бы файлы. Кроме того, если я не получаю vistors в течение 10 минут, тогда запуск один раз, когда следующий vistor прибывает, в порядке.

Есть ли стандартный способ выполнения этой задачи?

Благодаря!

Вы считали, что ваш скрипт запускает бесконечный цикл со sleep чтобы ждать 5 минут между итерациями?

 for (;;) { perform_actions(); sleep(300); } 

Кроме того, у вас может быть файл (например, is_running) и получить эксклюзивную блокировку на нем в начале вашего скрипта, который будет выпущен в конце. По крайней мере, так вы не сделаете ничего разрушительного.

Вы также можете объединить эти два решения.

 $fp = fopen("is_running", "r+"); /* is it already running? */ if (! flock($fp, LOCK_EX | LOCK_NB)) return; for (;;) { perform_actions(); sleep(300); } 

А затем задание cron все еще выполняется каждые 15 минут. Если процесс все еще запущен, он просто выйдет из строя, иначе он возобновит обновление и возобновит обновление каждые 5 минут.

Хромой ответ на хромую ситуацию (ISP, а не плакат). Расписание 12 заданий cron, все вызывающие один и тот же сценарий, каждый из которых выполняется один раз в час, но вызывается с другой отметкой в ​​5 минут.

 00 * * * * root echo "run at :00 of every hour" 05 * * * * root echo "run at :05 of every hour" 10 * * * * root echo "run at :10 of every hour" 

и т. д. до: 55. Но я согласен с моим оригинальным комментарием – найти нового провайдера 🙂

Если вы не можете сделать то, что предложил @Brandon, я бы порекомендовал приближаться к этому так же, как это делал я, когда писал демона в PHP (не лучшее решение, но я был практически вынужден это сделать).

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

 $fh = fopen('status_file', 'w'); /** * LOCK_NB is required because otherwise your script would stall until * a lock is aquired, queing a bunch of scripts. */ if(!flock($fh, LOCK_EX | LOCK_NB)) { exit 1; // our job is done here } 

Вы можете использовать Fat Controller для запуска скрипта с 5-минутными интервалами. В отличие от CRON, он гарантирует интервал времени, когда один экземпляр скрипта заканчивается, когда запускается другой.

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