Кластерный cron с одним сервером допускается только перекрытие
Я настроил балансировщики нагрузки: lb1 (активный) и lb2 (пассивный), Glustered веб-серверы: web1 (Активный), web2 (резервная копия) и некоторые кластерные базы данных. Как веб-серверы, так и базы данных A указал на VIP балансировщиков нагрузки.
Оба веб-сервера имеют свои копии заданий cron. Принимая на себя следующие задачи:
* * * * * echo $(hostname) >> crontab.txt
0 0 1 * * ~/bin/another/task 2>&1
С некоторым алгоритмом случайной блокировки:
lock_dir=~/.cronlock
pid_file=~/.cronlock/pid
if ( mkdir ${lock_dir} ) 2> /dev/null; then
echo $$ > $pid_file
trap 'rm -rf "$lock_dir"; exit $?' INT TERM EXIT
# Crons
rm -rf "$lock_dir"
trap - INT TERM EXIT
fi
Безопасно иметь что-то вроде
* * * * * ./lock_algorithm -f LOCK_FILE1 -c "echo $(hostname) >> crontab.txt"
0 0 1 * * ./lock_algorithm -f LOCK_FILE2 -c "~/bin/another/task 2>&1"
Куда я посылаю уникальное имя файла блокировки "per-cron-command" и команду для выполнения?
Под "безопасным" я подразумеваю web1 ИЛИ ЖЕ web2 будет работать, а не оба.
И если мне нужно перекрытие cron (например: каждую минуту я выполняю длинное задание, ограниченное текущей минутой)? Как получить web1снова выполняется cron, предполагая, что web1 активный "бегун cron"?
2 ответа
Похоже, вы пытаетесь создать семафор, который работает на разных серверах. Хотя кто-то пытался его построить, я не вижу, что он готов к производству. Вместо того, чтобы продвигать технологическую оболочку, было бы неплохо преобразовать вашу проблему во что-то, что соответствует доступной технологии.
У вашего сайта есть база данных? Вы можете использовать это для координации.
Если нет, то как насчет использования распределенной системы очередей, такой как kafka или 0mq?
Не уверен, что для вас возможно следующее, но вот моя идея:
Не уверен, какой кластерный стек / программное обеспечение вы используете, но вы могли бы представить кардиостимулятор и Corosync на
web1а такжеweb2и используйте для этого ocf ressource агентов. Чтобы дать вам представление о том, что это такое:primitive p_postfix ocf:heartbeat:postfix \ params config_dir="/etc/postfix" \ op monitor interval="10" primitive p_symlink ocf:heartbeat:symlink \ params target="/srv/postfix/cron" \ link="/etc/cron.d/postfix" \ backup_suffix=".disabled" \ op monitor interval="10" primitive p_cron lsb:cron \ op monitor interval=10 order o_symlink_before_cron inf: p_symlink p_cron colocation c_cron_on_symlink inf: p_cron p_symlink colocation c_symlink_on_postfix inf: p_symlink p_postfixЧто это будет делать, это следующее:
- Проверьте, есть ли файл с именем
postfixуже существует в/etc/cron.d, - Если это так, переименуйте его в
postfix.disabled(Помните,cronигнорирует определения заданий с точками в имени файла). - (Повторно) создать
postfixопределение задания в виде символической ссылки на/srv/postfix/cron, - Запустить снова
cronкогда это будет сделано.
- Проверьте, есть ли файл с именем
В этом примере запущен активный / пассивный кластер
postfix,Cronget выполняется только на активномpostfixузел.Вы можете изменить это, чтобы удалить
postfixи вместо этого включите ваш веб-сервер.
Изменить: Если вышесказанное "слишком много" для вас, вот еще одна идея: вы могли бы настроить HAProxy статистика, получите этот сайт в своем скрипте, проанализируйте его и действуйте соответственно в зависимости от имени хоста и статуса, испускаемого HAProxy,