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

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

Так что мой вопрос, могу ли я использовать посетителей для запускаPHP скрипт каждые 5 минут.Я легко могу записать последний раз, когда он запускался, и повторно запустить его по истекшему времени.

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

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

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

Ответы [ 5 ]

6 голосов
/ 26 августа 2010

Рассматривали ли вы просто, чтобы ваш скрипт запускал бесконечный цикл с 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 минут.

4 голосов
/ 26 августа 2010

Хромой ответ для неурожайной ситуации (провайдер, а не афиша). Запланируйте 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. Но я придерживаюсь своего первоначального комментария - найди нового интернет-провайдера:)

1 голос
/ 26 августа 2010

Если вы не можете сделать то, что предложил @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
}
0 голосов
/ 01 декабря 2014

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

0 голосов
/ 12 января 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...