Healthcheck: как сделать страницу состояния своего сервиса
3 мин чтения
Healthcheck: как сделать страницу состояния своего сервиса

Healthcheck: как сделать страницу состояния своего сервиса

Healthcheck — специальный адрес, по которому сервис отвечает, здоров ли он. Сделанный правильно, он падает раньше, чем это заметят пользователи. Сделанный неправильно — либо врёт, либо сам становится причиной аварии.

Зачем нужен отдельный адрес

Проверять главную страницу для этой цели неудобно: она тяжёлая, кэшируется и может открываться даже тогда, когда база данных недоступна. Healthcheck решает обратную задачу — он лёгкий, не кэшируется и честно ломается, когда сломано что-то важное внутри.

Его читают сразу несколько потребителей: балансировщик решает, слать ли на этот экземпляр трафик; оркестратор — перезапускать ли контейнер; внешний мониторинг — будить ли дежурного. Отсюда и требования: быстрый ответ, однозначный код, никакой лишней информации наружу.

Три уровня проверки

Смешивать их в одном адресе — самая частая ошибка. Задачи у них разные.

Уровень Отвечает на вопрос Кто читает
Liveness Процесс жив и не завис? Оркестратор — решает, перезапускать ли
Readiness Готов ли принимать трафик прямо сейчас? Балансировщик — решает, слать ли запросы
Deep / dependencies Работают ли база, кэш, очередь, внешние API? Мониторинг и дежурный

Практическое следствие: если положить проверку базы данных в liveness, оркестратор начнёт перезапускать здоровые экземпляры при недоступной базе — перезапуск ничего не починит, а сервис будет метаться. Проверки зависимостей место в отдельном, более редком запросе.

Что отдавать в ответе

Главное — код ответа: 200 при здоровом сервисе и 503 при неготовности. Именно на код смотрят автоматика и внешний мониторинг, тело ответа для них вторично.

Тело полезно человеку, который открыл адрес во время разбора аварии. Достаточно короткого JSON со статусом и списком зависимостей:

{
  "status": "ok",
  "version": "1.4.2",
  "checks": {
    "db": "ok",
    "cache": "ok",
    "queue": "degraded"
  }
}

Поле с версией экономит много времени: по нему сразу видно, доехал ли релиз до этого экземпляра. А состояние вроде «degraded» позволяет отличить «всё сломано» от «работает, но без второстепенной функции» — и не будить человека ночью из-за второго.

Четыре типичные ошибки

Слишком тяжёлый healthcheck. Если на каждый запрос выполняется несколько обращений к базе, а балансировщик опрашивает адрес раз в секунду с десятка узлов, проверка сама создаёт заметную нагрузку. Результаты проверки зависимостей стоит кэшировать на несколько секунд.

Ответ кэшируется. Прокси или CDN запоминает ответ «всё хорошо» и продолжает отдавать его, когда сервис уже лёг. Healthcheck обязан отдаваться с запретом кэширования — иначе он бесполезен.

Наружу уходит лишнее. Адреса внутренних серверов, версии библиотек, тексты ошибок с деталями подключения — подарок тому, кто изучает ваш сервис. Публичный healthcheck должен быть скупым, подробный — закрытым или доступным только из внутренней сети.

Проверка чужой доступности внутри своей. Если ваш healthcheck отдаёт 503 из-за недоступного внешнего API, балансировщик выведет из работы ваш совершенно здоровый сервис. Внешние зависимости отражайте статусом в теле ответа, а не кодом.

Внутренний мониторинг не заменяет внешний

Healthcheck отвечает на вопрос «здоров ли сервис изнутри». Он ничего не скажет, если сломался DNS, истёк сертификат, лёг канал у провайдера или сайт закрыт файрволом от половины страны: изнутри всё выглядит прекрасно. Поэтому его опрашивают снаружи, из другой сети.

Как это устроено в Пруфене

Пруфен опрашивает ваш healthcheck снаружи: проверка доступности с интервалом от 2 минут из 13 точек следит за кодом ответа и временем, а проверка контента — за строкой в теле ответа, так что можно отличить status ok от degraded. Уведомления приходят на Email, в Telegram, в Макс или звонком, а когда сервис поднимется — второе.

Частые вопросы

Закрывать ли healthcheck авторизацией? Публичный лёгкий адрес обычно оставляют открытым — иначе его не сможет опросить внешний мониторинг. Подробную версию с составом зависимостей закрывают: либо отдельным адресом во внутренней сети, либо простым токеном в параметре.

Какой адрес выбрать? Подойдёт любой предсказуемый: часто используют /health или /healthz. Важнее не имя, а то, чтобы он не попадал в кэш, не индексировался поисковиками и был описан в документации команды.

Нужен ли healthcheck небольшому сайту на CMS? Отдельный адрес обычно избыточен: хватает проверки ключевых страниц и содержимого на них. Healthcheck оправдан там, где есть балансировка, несколько экземпляров или зависимости, которые ломаются независимо от сайта.

Как быть с медленными зависимостями? Ставьте им короткий таймаут и кэшируйте результат. Проверка, которая сама ждёт ответа пять секунд, превращает healthcheck в источник ложных срабатываний по таймауту у всех, кто его опрашивает.

Была ли статья полезна?

Начните мониторинг прямо сейчас

Бесплатный тариф — до 5 проверок. 150 ₽ на баланс при регистрации.

Создать аккаунт