Кластерный 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
,Cron
get выполняется только на активномpostfix
узел.Вы можете изменить это, чтобы удалить
postfix
и вместо этого включите ваш веб-сервер.
Изменить: Если вышесказанное "слишком много" для вас, вот еще одна идея: вы могли бы настроить HAProxy
статистика, получите этот сайт в своем скрипте, проанализируйте его и действуйте соответственно в зависимости от имени хоста и статуса, испускаемого HAProxy
,