Что я использую, когда задания 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 и не беспокоиться о гонке условия.