Задачи Cron на веб-серверах с балансировкой нагрузки - PullRequest
14 голосов
/ 23 июня 2011

Я ищу лучшее решение для обработки наших задач cron в среде с балансировкой нагрузки.

В настоящее время есть :

  • PHP-приложение, работающее на 3 серверах CentOS за балансировщиком нагрузки.
  • Задачи, которые нужно запускать периодически, но только на одной машине одновременно.
  • Старый добрый cron, настроенный для запуска этих задач на первом сервере.
  • Проблемы, если первый сервер не работает по какой-либо причине.

Ищу :

  • Что-то более надежное и децентрализованное.
  • Балансировка нагрузки для задач, чтобы несколько задач выполнялись только один раз, но на случайных / разных серверах для распределения нагрузки.
  • Предотвращение запуска задач при отключении первого сервера.
  • Возможность управлять задачами и в идеале просматривать сводные отчеты с помощью веб-интерфейса.
  • Уведомления, если что-то идет не так.

Решение не нужно реализовывать на PHP, но было бы неплохо, так как это позволило бы нам легко настроить его при необходимости.

Я нашел два проекта, которые выглядят многообещающе. GNUBatch и Планировщик заданий . Скорее всего, будет дальше проверять оба, но мне интересно, если у кого-то есть лучшее решение для вышеупомянутого.

Спасибо.

Ответы [ 3 ]

5 голосов
/ 05 декабря 2013

Вы можете использовать эту маленькую библиотеку, которая использует redis для создания временной временной блокировки:

https://github.com/AlexDisler/MutexLock

Серверы должны быть идентичными и иметь одинаковую конфигурацию cron. Сервер, который первым создаст блокировку, также выполнит задачу. Другие серверы увидят блокировку и выйдут без выполнения каких-либо действий.

Например, в файле php, который выполняет запланированное задание:

MutexLock\Lock::init([
  'host'   => $redisHost,
  'port'   => $redisPort
]);

// check if a lock was already created,
// if it was, it means that another server is already executing this task
if (!MutexLock\Lock::set($lockKeyName, $lockTimeInSeconds)) {
  return;
}

// if no lock was created, execute the scheduled task
scheduledTaskThatRunsOnlyOnce();

Чтобы выполнить задачи децентрализованным способом и распределить нагрузку, взгляните на: https://github.com/chrisboulton/php-resque Это php-порт ruby-версии resque, и он хранит данные в одном и том же точном формате, поэтому вы можете использовать https://github.com/resque/resque-web или http://resqueboard.kamisama.me/ для мониторинга рабочих и просмотра отчетов

3 голосов
/ 23 июня 2011

Предполагается, что у вас есть база данных, размещенная не на одном из этих трех серверов;

Напишите скрипт-оболочку, который запускается в cron и принимает в качестве аргумента программу, которую вы запускаете.Самое первое, что он делает, - подключается к удаленной базе данных и проверяет, когда в последний раз запись была вставлена ​​в таблицу (созданную для этой оболочки).Если время последней вставки больше, чем ожидалось, вставьте в таблицу новую запись с текущим временем и выполните аргумент оболочки (задание cron).

Завершение оболочки накаждый сервер, каждый установленный X минут позади другого (сервер A работает в верхней части часа, сервер B работает в 5 минут, C в 10 минут и т. д.).

Первый сервер всегда будет выполнять cronВо-первых, два других сервера никогда не будут.Если первый сервер выйдет из строя, второй сервер увидит, что он не работал, и запустит его.

Если вы также запишите в таблице, какой сервер выполнял задание, у вас будетжурнал, когда / где был выполнен скрипт.

0 голосов
/ 29 июля 2012

Разве это не идеальная ситуация для использования очереди сообщений / задач?

...