Monit следит за тем, что службы работают, и поднимает их, когда они падают. Первый вопрос, который здесь уместен: зачем это, если systemd умеет то же самое одной строкой Restart=always?
Ответ определяет всю настройку. systemd видит, что процесс завершился, и запускает его заново. Он не знает, отвечает ли служба на запросы. PHP-FPM, упёршийся в лимит процессов, для systemd жив и здоров, а сайт при этом отдаёт 502. MySQL, у которого кончилось место, продолжает работать процессом и не выполняет ни одного запроса. Monit проверяет не факт существования процесса, а его поведение: отвечает ли порт, что возвращает HTTP-запрос, сколько занято памяти.
Отсюда правило: systemd оставляем как есть, а Monit добавляем ради функциональных проверок. Дублировать перезапуск упавшего процесса смысла нет.
Настройка
sudo apt install monit
Основной файл — /etc/monit/monitrc, свои проверки кладутся отдельными файлами в /etc/monit/conf.d/. Начало обычное:
set daemon 60
set logfile /var/log/monit.log
set mailserver localhost
set alert admin@example.com
Опрос раз в минуту — разумный баланс. Более частый добавляет нагрузку и повышает риск ложного перезапуска на секундной задержке.
Веб-интерфейс: только локально
У Monit есть встроенная веб-страница, и по умолчанию её включают примерно так, как показано в первом попавшемся руководстве, — на всех адресах. Получается панель управления службами сервера, доступная из интернета. Правильный вариант:
set httpd port 2812 and
use address localhost
allow localhost
allow admin:'длинный-пароль'
Доступ снаружи — через SSH-туннель:
ssh -L 2812:localhost:2812 user@203.0.113.25
После этого страница открывается на своём компьютере по адресу localhost:2812, и наружу ничего не торчит.
Проверки, которые имеют смысл
Веб-сервер — не по факту процесса, а по ответу:
check process nginx with pidfile /run/nginx.pid
start program = "/bin/systemctl start nginx"
stop program = "/bin/systemctl stop nginx"
if failed host 127.0.0.1 port 80 protocol http
request "/" status = 200
for 3 cycles then restart
if 3 restarts within 10 cycles then unmonitor
Три строки здесь важнее остальных.
protocol http ... status = 200 — это и есть проверка, ради которой всё затевалось: сервер обязан вернуть страницу, а не просто держать открытый порт.
for 3 cycles — не реагировать на единичный сбой. Без этого Monit перезапустит службу из-за одного медленного ответа под нагрузкой, чем только ухудшит положение.
if 3 restarts within 10 cycles then unmonitor — обязательная строка. Если служба не поднимается из-за ошибки в конфигурации, Monit будет перезапускать её бесконечно, добавляя нагрузку и заполняя логи. Эта строка означает: три неудачные попытки — прекратить и оставить сообщение. Дальше нужен человек, автоматика уже не поможет.
Место на диске проверяется без всякой автоматики, просто сообщением:
check filesystem rootfs with path /
if space usage > 85% then alert
if inode usage > 85% then alert
Строка про inode нужна отдельно: они кончаются независимо от места, и без неё эта ситуация останется незамеченной.
Проверка конфигурации
sudo monit -t
sudo systemctl reload monit
sudo monit summary
sudo monit status
monit -t проверяет синтаксис до применения. monit summary даёт короткую таблицу состояний — с неё стоит начинать разбор любой проблемы.
И проверьте отправку почты. Monit сообщает о событиях письмом, и если отправка не настроена, оповещения не будет — служба перезапустится, вы об этом не узнаете, а именно повторяющиеся перезапуски и есть главный сигнал. Смотреть их можно и в логе: /var/log/monit.log.
Чего Monit не делает
Он не устраняет причину. Перезапуск — это отсрочка, и постоянно перезапускаемая служба означает, что где-то не хватает памяти, кончается место или течёт приложение. Ценность инструмента не в самом перезапуске, а в счётчике: три перезапуска nginx за сутки — это диагноз, который иначе остался бы незамеченным, потому что сайт всё это время работал.
Поэтому смотреть надо не на текущее состояние (оно почти всегда зелёное), а на историю: сколько раз за неделю что-то поднималось само. Как это выглядит на одной странице — на демо ниже.