ADG Оставить заявку
Блог Автоматизация 4 мин чтения

Nagios event handlers: apache падает - скрипт поднимает, дежурный спит

Настроили Nagios 3.0 alpha event handlers для автоперезапуска Apache при критическом алерте - за месяц три восстановления без единого звонка дежурному.

Контекст момента

Nagios 3.0 alpha выходит в 2007 году с улучшенным NRPE и поддержкой event handlers

Nagios 3.0 пока в альфе, но event handlers там задокументированы достаточно внятно, чтобы рискнуть попробовать в одном из managed-проектов. Рискнули. Понравилось.

Предыстория

У клиента - интернет-магазин на LAMP, Apache + PHP + MySQL на одном сервере. Нагрузка нормальная, не экстремальная, но Apache периодически ложится: или процессы кончились из-за медленных запросов к базе, или что-то ещё. Паттерн известный: раз в несколько недель ночью или в выходные апач падает, клиент обнаруживает по звонку от покупателей, звонит нам, мы поднимаем. Мониторинг был - Nagios 2.x с активными проверками по HTTP, алерт уходил на почту и на телефон дежурному. Дежурный просыпался, лез на сервер, делал service httpd restart, шёл обратно спать. Полчаса от падения до восстановления - в лучшем случае.

Это не сложная проблема. Это просто руки, которые не были нужны.

Что такое event handlers в Nagios 3

Event handler - это скрипт, который Nagios запускает автоматически при изменении состояния сервиса или хоста. Не просто «отправить уведомление», а именно выполнить произвольную команду. В Nagios 2.x эта возможность тоже была, но работала менее предсказуемо. В 3.0 alpha логика выполнения хендлеров стала чище - документация это явно оговаривает, и на практике мы это подтвердили.

Хендлер получает четыре аргумента: состояние сервиса (OK, WARNING, CRITICAL, UNKNOWN), тип состояния (HARD или SOFT), номер попытки и текущее состояние. Это позволяет не реагировать на первый же SOFT CRITICAL - подождать, пока Nagios сделает несколько попыток и убедится, что это не кратковременный сбой.

Как настроили

Конфигурация в services.cfg:

define service {
    host_name               webserver
    service_description     HTTP
    check_command           check_http
    max_check_attempts      3
    event_handler_enabled   1
    event_handler           restart-apache
}

Команда в commands.cfg:

define command {
    command_name    restart-apache
    command_line    /etc/nagios/eventhandlers/restart-apache.sh $SERVICESTATE$ $SERVICESTATETYPE$ $SERVICEATTEMPT$
}

Скрипт /etc/nagios/eventhandlers/restart-apache.sh простой - три десятка строк. Проверяет, что состояние CRITICAL и тип HARD (то есть Nagios уже три раза попробовал и убедился). Тогда:

  1. Делает service httpd restart
  2. Ждёт пять секунд
  3. Проверяет, запустился ли процесс
  4. Пишет запись в отдельный лог с меткой времени и результатом
  5. Отправляет письмо на специальный адрес с пометкой «автоматическое восстановление»

Скрипт запускается от имени пользователя nagios - для этого пришлось добавить строку в /etc/sudoers, разрешающую запуск service httpd restart без пароля только для этого пользователя. Остальные права у nagios минимальные, как и должно быть.

NRPE в Nagios 3.0 alpha тоже подтянули: проверки запускаются на удалённой стороне стабильнее, timeout-ы обрабатываются корректнее. Это важно, когда event handler срабатывает и надо через секунду уже видеть актуальное состояние сервиса, а не кешированный результат.

Месяц в работе

За четыре недели Apache ложился три раза. Все три раза - ночью. Ни разу дежурный не просыпался.

Схема работала так: Nagios детектировал CRITICAL на HTTP-чеке, делал три попытки за шесть минут (интервал проверки две минуты), убеждался что это HARD CRITICAL, запускал хендлер. Хендлер перезапускал Apache, следующая проверка возвращала OK. Всё это занимало около семи-восьми минут от момента падения до восстановления. Уведомление дежурному уходило, но к моменту получения проблема уже была решена.

Клиент узнал об инцидентах из еженедельного отчёта, который мы ему отправляем. Его реакция была примерно такая: «А, я даже не заметил». Это и было целью.

Важный нюанс: автоперезапуск - не решение проблемы, а снижение её стоимости. Apache падает по какой-то причине, и эту причину мы параллельно разбираем - смотрим в error_log, анализируем server-status в момент нагрузки, проверяем конфигурацию MaxClients и время выполнения тяжёлых запросов. Хендлер убирает симптом быстро; устранение первопричины - отдельная работа.

Второй нюанс: скрипт надо защитить от зацикливания. Если Apache не поднимается после перезапуска, хендлер не должен долбить restart бесконечно. У нас в скрипте есть проверка: если после restart сервис не поднялся - только уведомление, никакого повторного запуска. В таком случае дежурный всё же просыпается - но это уже серьёзная ситуация, требующая ручного вмешательства.

Куда двигаемся

Сейчас пишем похожий хендлер для MySQL - там паттерн другой, просто restart не всегда безопасен, нужна проверка таблиц. Логика будет сложнее: посмотреть, есть ли запущенные транзакции, дождаться завершения или прибить зависшие по таймауту, потом уже restart.

Весь этот managed-мониторинг с хендлерами становится заметно интереснее, чем просто «алерт на почту и ждём дежурного». Monitoring-as-automation - пусть и в простом виде - реально меняет ощущение от ночных дежурств.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.