Что я использую, когда задания cron недостаточно? (РНР)
Я пытаюсь выяснить наиболее эффективный способ запуска довольно сложной задачи PHP тысячами раз в день. Он должен сделать IMAP-соединение с Gmail, перебрать электронные письма, сохранить эту информацию в базе данных и сохранить изображения локально.
Выполнение этой задачи каждый раз с использованием cron не является чем-то большим, но мне нужно запускать его каждую минуту, и я знаю, что в конце концов кроны начнут работать друг над другом и вызовут проблемы с памятью.
Каким будет следующий шаг, когда вам нужно эффективно выполнять задачу несколько раз в минуту? Я читал о beanstalk и pheanstalk, и я не совсем уверен, что это будет делать то, что мне нужно. Мысли???
Ответы
Ответ 1
Создайте механизм блокировки, чтобы сценарии не перекрывались. Это довольно просто, поскольку скрипты запускаются только каждую минуту, достаточно простого файла .lock:
<?php
if (file_exists("foo.lock")) exit(0);
file_put_contents("foo.lock", getmypid());
do_stuff_here();
unlink("foo.lock");
?>
Это позволит убедиться, что скрипты не запускаются параллельно, вам просто нужно убедиться, что .lock файл удален, когда программа выходит, поэтому у вас должна быть одна точка выхода (кроме выхода в начале).
Хорошая альтернатива - как предложил Брайан Роуч - это выделенный серверный процесс, который работает все время и поддерживает соединение с сервером IMAP. Это значительно сокращает накладные расходы и не намного сложнее, чем писать обычный php script:
<?php
connect();
while (is_world_not_invaded_by_aliens())
{
get_mails();
get_images();
sleep(time_to_next_check());
}
disconnect();
?>
Ответ 2
Я не парень PHP, но... что мешает вам запустить ваш script в качестве демона? Я написал много perl script, которые делают именно это.
Ответ 3
У меня есть несколько таких скриптов, в которых я не хочу запускать их из cron, если они складываются.
#!/bin/sh
php -f fetchFromImap.php
sleep 60
exec $0
Часть exec $0
запускает перезапуск script, заменяя себя в памяти, поэтому он будет работать вечно без проблем. Любая память, используемая PHP скрипт, очищается всякий раз, когда она завершается, так что это тоже не проблема.
Простая строка запустит его и поместит в фоновый режим:
cd /x/y/z ; nohup ./loopToFetchMail.sh &
или его можно запустить аналогичным образом, когда машина запускается с помощью различных средств (например, Cron '@reboot....')
Ответ 4
fcron http://fcron.free.fr/ не будет запускать новое задание, если старый еще запущен, вы можете использовать @ 1 command
и не беспокоиться о гонке условия.