Скрипт восстановления сервисов в случае их отказа
Задача
Одна из типовых ситуаций, которые возникают при эксплуатации web-сайтов - отказ сервиса HTTPD или СУБД. В данном примере, мы будем мониторить состояние двух наиболее часто применяемых сервисов: apache2 и mariadb. Отказ или аварийная остановка сервиса может произойти по ряду причин. Наиболее частые причины следующие:
- переполнение оперативной памяти в сервере и, как следствие, отработка механизма
OOM (Out of Memory) kill; - злонамеренная атака на сервис (bruteforce, SQL-injecting, DDoS и прочие виды атак);
- переполнение дискового пространства.
Под понятием сервер подразумевается аппаратный сервер или виртуальная машина.
Естественно, это решение можно легко перенастоить и для других применений (сервисов).
Решение
Для того, чтобы автоматически восстановить работоспособность сервиса (web-сайта, как частный случай), создаем программу по имени /usr/local/bin/watcher:
#!/bin/bash
SRVL=(
mariadb
apache2
)
MIG=$(date +%y%m%d%H%M)
LOGF="/var/log/restart.log"
for SRV in ${SRVL[@]}; do
if systemctl is-failed --quiet $SRV || ! systemctl is-active --quiet $SRV; then
/usr/bin/systemctl start $SRV
echo ${MIG}: ${SRV} restart >> $LOGF
fi
done
Эта программа сможет автоматически восстановить работу сервисов, перечисленных в массиве ${SRVL} в случае отказа по двум первым из трех вышеприведенных причин.
Чтобы восстановить работоспособность сервисов, отказавших по причине переполнения дискового пространства - к сожалению, в большинстве случаев, требуется ручное вмешательство - надо смотреть, какие именно файлы можно удалить (как правило логи). В некоторых случаях - когда удалять уже нечего, поможет только расширение диска или подключение дополнительного диска.
Добавляем ее в crontab пользователя root для запуска каждые 2 минуты:
Можно обойтись и без записи в планировщик - тогда надо создать файл сервиса и прописать в нем вызов прогаммы watcher.
Тестирование
Для того, чтобы смоделировать состояние переполнения оперативной памяти, смонтируем ФС tmpfs с размером, равным размеру RAM - в нашем примере 2Gb:
Создаем файл контроля состояния сервиса oom_test:
#!/bin/bash
SRV=$1
if [[ -n $SRV ]]; then
watch "if systemctl is-failed --quiet '${SRV}' || ! systemctl is-active --quiet '${SRV}'; then echo failed; else echo active; fi"
fi
Запускаем контроль, например, по сервису mariadb
Видим на экране, где запущен oom_test, что сервис перешел в состояние failed.
Далее, искусственно уменьшим потребление ОЗУ, например до 900Кб:
И в течении максимум двух минут, мы увидим, что сервис автоматически перешел в состояниеactive. Это свидетельствует о том, что наша программа правильно отработала и работоспособность web-сайта восстановилась в автоматическом режиме.
После окончания тестирования, не забываем очистить и отключить RAM-диск:
Опубликовано: 15.02.2025