У меня есть скрипт php, который должен запускаться раз в 5 минут. В настоящее время я использую задание cron для его запуска (и оно отлично работает), но мой хост позволяет отработать не менее 15 минут.
Поэтому мой вопрос заключается в том, могу ли я использовать посетителей для запуска каждого сценария php каждый раз 5 минут. Я легко могу записать последний раз, когда он запускался, и повторно запустить его, основываясь на прошедшем времени.
Однако меня беспокоит состояние гонки. Важно, чтобы скрипт запускался только один раз каждые 5 минут.
Мой сценарий занимает около 60 секунд. За это время пишет в пару файлов. Если скрипт запускался более одного раза, он испортил бы файлы. Кроме того, если я не получу ни одного посетителя в течение 10 минут, затем работает один раз, когда появляется следующий резистор.
Есть ли какой-нибудь стандартный способ выполнить эту задачу?
Спасибо!
Рассматривали ли вы, чтобы ваш скрипт запускал бесконечный цикл с сна
для ожидания 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 минут.
Если вы не можете сделать то, что предложил @Brandon, я бы рекомендовал подойти к этому так же, как я делал при написании демона на PHP (не лучшее решение, но я был практически вынужден сделать это ).
В моем случае сценарий также обращался к файлу (журнала) и выполнял его обработку, после чего вставлял результаты в базу данных. Поэтому, чтобы убедиться, что у меня нет двух файлов, работающих одновременно, я создал файл «статуса», на котором скрипт получил блокировку и, если не смог сделать это, если изящно потерпел неудачу.
$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
}
Неубедительный ответ на неуместную ситуацию (провайдер, а не плакат). Запланируйте 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. Но я остаюсь при своем первоначальном комментарии - найдите нового провайдера :)