Скрипт восстановления сервисов в случае их отказа
Задача
Одна из типовых ситуаций, которые возникают при эксплуатации 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