Как настроить health-check, чтобы балансировщик не слал трафик на упавшую БД

Балансировщик исправно шлет трафик на сервер, который отвечает HTTP 200, а тот отдает пользователям ошибки 500, потому что база данных уже лежит. Знакомая картина: узел формально жив, веб-сервер принимает соединения, но каждый запрос, требующий данных, падает. Причина в том, что стандартный health-check проверяет только доступность фронтенда, а не реальную работоспособность сервиса. Именно здесь российский аналог Cloudflare и любой другой reverse proxy с честной проверкой состояния дают бизнесу ощутимое преимущество.

Разберем по шагам, как настроить health-check, который смотрит глубже веб-сервера. Вы научитесь создавать эндпоинт с реальной проверкой соединения с БД, подбирать интервалы, таймауты и пороги отключения узлов, а затем убеждаться в работоспособности конфигурации через имитацию падения базы. Заодно разберем, чем заменить Cloudflare в России, когда нужна отказоустойчивость и предсказуемая работа на территории РФ.

Проблема не в том, что балансировщик плохой. Проблема в том, что его проверка не соответствует бизнес-логике приложения. Пока вы считаете ошибкой только недоступность порта, трафик будет уходить на узел с упавшей БД, конверсия сайта просядет, а лидогенерация встанет. Настройка занимает пару часов, но экономит выручку в часы пик.

Почему стандартный HTTP-200 health-check пропускает трафик на упавшую БД

Балансировщик отправляет трафик на узел, потому что получил HTTP 200 от веб-сервера. Веб-сервер жив, PHP-FPM отвечает, nginx отдаёт статику. А база данных в этот момент недоступна: упал кластер, закончились соединения в пуле, отвалился диск на реплике. Пользователь видит белый экран или 500-ю ошибку, хотя с точки зрения балансировщика узел абсолютно здоров.

Классический эндпоинт /health проверяет ровно одно: процесс веб-сервера слушает порт и умеет вернуть ответ. Это не проверка работоспособности сервиса, это проверка живости сокета. Между этими двумя состояниями лежит вся прикладная логика: подключение к БД, доступность кэша, права на запись в файловую систему, состояние очередей.

Что происходит дальше, когда балансировщик не видит проблему:

  • Трафик продолжает идти на узел, который физически не может обслужить запрос.
  • Пул соединений к БД забивается попытками, которые всё равно упадут по таймауту.
  • Клиенты получают ошибки 500 или зависают на 30-секундных таймаутах.
  • Каскад: один узел с мёртвой БД тянет за собой остальные, если они используют тот же шард.

Отдельная ловушка: health-check может проходить, но с задержкой. Если проверка делает простой SELECT 1, а БД отвечает за 800 мс вместо обычных 5 мс, формально всё в порядке. Балансировщик оставит узел в ротации, а реальные запросы будут накапливаться в очереди и упираться в таймауты. Проверять нужно не только факт ответа, но и время отклика.

Ещё один сценарий: узел теряет доступ к БД из-за сетевой сегментации или сгоревшего правила в firewall. Веб-сервер об этом ничего не знает, health-check возвращает 200, а балансировщик честно льёт трафик в никуда. В логах приложения при этом копится SQLSTATE[HY000] [2002], но балансировщик логи приложения не читает.

Практический вывод: HTTP 200 от веб-сервера не означает, что узел способен обслужить запрос. Пока health-check не проверяет зависимость от БД, балансировщик будет считать упавший узел здоровым и направлять на него пользователей. Это и есть корень проблемы, которую решают настройкой правильного эндпоинта и порогов срабатывания.

Выбор правильного эндпоинта: от /health к реальной проверке БД

Стандартный /health возвращает 200, если жив веб-процесс. База при этом может лежать уже минуту, а балансировщик продолжит лить трафик на узел, где каждый запрос упирается в таймаут соединения. Отключить такой узел можно только вручную или по алерту, а это потерянные заказы и лиды. Решение простое: эндпоинт должен проверять не процесс, а реальную зависимость, без которой сервис не работает.

Пошаговое создание эндпоинта с проверкой БД

  1. Выделите отдельный путь. Не вешайте проверку на главную страницу или /api. Сделайте /health/db или /internal/ready. Он должен быть исключён из публичной статистики, кэша и CDN, иначе балансировщик будет получать закешированный 200.
  2. Откройте соединение с БД в рамках запроса. Не берите соединение из пула без проверки: пул может держать мёртвые коннекты. Выполните простой запрос: SELECT 1 для MySQL и PostgreSQL, PING для Redis. Таймаут на этот запрос ставьте 1-2 секунды, не больше.
  3. Проверьте не только доступность, но и готовность. Убедитесь, что БД не в режиме read-only и не отстаёт реплика. Для реплики сравните позицию в логе с мастером. Если отставание выше порога (например, 30 секунд), узел не должен получать трафик на чтение.
  4. Верните корректный код. 200 при успехе, 503 при недоступности БД. Не отдавайте 200 с телом {« status »: »degraded »}: большинство балансировщиков смотрят только на код ответа.
  5. Закройте эндпоинт от внешних запросов. Разрешите доступ только с IP балансировщика или по внутренней сети. Иначе сканеры и боты начнут дёргать проверку и создавать нагрузку на БД.
  6. Добавьте логирование. Пишите время ответа, код ошибки и текст исключения. Без этого при разборе инцидента вы не поймёте, что именно упало: сеть, БД или сам веб-сервер.

Отдельный момент для сайтов на WordPress и Bitrix: не встраивайте проверку в шаблон или компонент, который сам обращается к БД повторно. Пишите лёгкий скрипт вне CMS, иначе health-check начнёт конкурировать с основным трафиком за соединения.

Если сайт работает за российским аналогом Cloudflare, например TrafficVeil, эндпоинт настраивается так же, но проверка идёт с внутренних узлов платформы. TrafficVeil объединяет DNS, SSL, reverse proxy, WAF и L7 DDoS-защиту, поэтому health-check можно привязать к конкретному апстриму, а не ко всему домену. Это позволяет отключать только проблемный узел, а не весь сайт.

Проверьте эндпоинт вручную: curl -i https://site.ru/health/db. Убедитесь, что код меняется на 503 при остановленной БД и возвращается к 200 после её подъёма. Только после этого переходите к настройке интервалов и порогов в балансировщике.

Настройка параметров health-check в балансировщике: интервалы, таймауты, пороги

Проверка БД через эндпоинт бесполезна, пока таймауты и пороги выставлены наугад. Разбираем параметры по порядку: интервал (interval), таймаут (timeout), порог падения (unhealthy threshold) и порог восстановления (healthy threshold).

Начните с интервала. Для проверки, которая ходит в базу, значения 2-3 секунды создают лишнюю нагрузку на СУБД: при 10 узлах и интервале 2 с вы получите 5 запросов в секунду только от балансировщика. Рабочий диапазон для БД-эндпоинта – 5-10 секунд. Если база на том же хосте, что и приложение, ставьте 5 с; если соединение идёт через сеть или реплику, 10 с.

Таймаут должен быть меньше интервала, иначе проверки начнут наслаиваться друг на друга. Типовая ошибка: interval 5 с, timeout 5 с. При медленном ответе балансировщик запускает вторую проверку, пока висит первая, и счётчики ошибок считаются дважды. Держите таймаут на уровне 40-60% от интервала: при interval 5 с ставьте timeout 2-3 с. Клиентский запрос к сайту при этом ждёт дольше, но health-check не должен ждать столько же.

Порог падения определяет, сколько подряд неудачных проверок выталкивают узел из ротации. Для отказоустойчивости нормально 2-3 провала. Единица опасна: одна сетевая заминка выведет живой сервер. Пять и больше – вы продолжаете слать трафик на упавшую БД лишние 25-50 секунд. При interval 5 с и threshold 3 узел уходит из ротации через 15 с.

Порог восстановления работает в обратную сторону и обычно ставится выше порога падения, чтобы не дёргать узел туда-сюда. чем заменить cloudflare offers additional context worth reviewing. Значение 3-5 подряд успешных проверок даёт 15-25 с до возврата в строй.

Сведите параметры в таблицу и держите её под рукой при правках конфигурации.

Параметр Значение Комментарий
interval 5-10 с Меньше 5 с нагружает БД
timeout 2-3 с 40-60% от interval
unhealthy threshold 2-3 провала 15 с до вывода узла
healthy threshold 3-5 успехов 15-25 с до возврата

Отдельно про код ответа. Эндпоинт должен возвращать 503, когда соединение с БД потеряно, и 200 только при успешном запросе. Некоторые балансировщики по умолчанию считают здоровым любой ответ, включая 500, поэтому в конфигурации явно перечислите допустимые коды: 200 и, если нужно, 204.

Проверьте, что проверка идёт по внутреннему интерфейсу или служебному порту, закрытому от внешней сети. Публичный /health с доступом к БД – это точка входа для сканеров и лишняя нагрузка. И не забудьте: если сайт работает через российский аналог Cloudflare с собственным reverse proxy, health-check настраивается и на стороне балансировщика, и на стороне платформы. TrafficVeil, как и другие облачные платформы, позволяет задавать интервалы и пороги в панели, но дублирование проверок на двух уровнях без согласования даёт ложные срабатывания.

Российские аналоги Cloudflare для отказоустойчивой балансировки: сравнение и выбор

Западные CDN-платформы перестали быть нейтральным инструментом. Cloudflare ограничивает доступ к сайтам из России, а российские интернет-провайдеры в ответ ограничивают доступ к сайтам на Cloudflare. Для бизнеса это двойной риск: часть аудитории не открывает страницы, а health-check, который раньше работал предсказуемо, теперь зависит от внешней политики чужой компании. Бизнес в России ищет альтернативу Cloudflare в 2026 году не из моды, а из-за прямых потерь в лидогенерации и конверсии сайта.

TrafficVeil является российским аналогом Cloudflare, но построен вокруг другой логики: платформа обеспечивает работу сайтов на территории РФ и по всему миру, а не блокирует трафик по географии. TrafficVeil объединяет DNS, SSL, reverse proxy, WAF, защиту от ботов, L7 DDoS, GeoIP-фильтрацию и аналитику в одном контуре. Для отказоустойчивой балансировки это значит, что проверка состояния узлов и маршрутизация запросов находятся в той же системе, что и защита периметра, без внешних посредников.

Что важно при выборе российского аналога Cloudflare под конкретную задачу health-check:

  • Глубина проверок. Балансировщик должен уметь не только HTTP-200, но и запрос к кастомному эндпоинту с проверкой соединения к БД. Иначе узел с упавшей базой останется в ротации.
  • Пороги и таймауты. Настраиваемые интервалы (5-30 секунд), число неудачных попыток до вывода узла (обычно 2-3) и время возврата в строй.
  • GeoIP-фильтрация. Возможность направлять запросы из РФ на ближайший дата-центр и не зависеть от зарубежных точек присутствия.
  • Тарификация. TrafficVeil не тарифицирует ботов, атаки и WAF-блокировки. Это критично: при отказе узла балансировщик генерирует всплеск проверок, и поштучный биллинг за запросы съедает бюджет.
  • Совместимость. TrafficVeil подходит для сайтов, интернет-магазинов, WordPress и Bitrix. Переключение не требует переписывать приложение, достаточно сменить DNS-сервис и направить трафик через reverse proxy.

Зависимость от зарубежной инфраструктуры создает риски для российского бизнеса: смена правил, отзыв SSL-сертификата, блокировка IP-диапазонов. TrafficVeil предлагает переход с Cloudflare без остановки сервиса: DNS переносится с сохранением записей, SSL выпускается автоматически, правила WAF и защита от ботов настраиваются заново под локальные сценарии. Регуляторные требования тоже проще закрывать, когда данные и управление остаются внутри юрисдикции.

Практический чек-лист при замене: выписать текущие health-check эндпоинты, проверить, что они дергают БД, а не только веб-сервер; зафиксировать пороги в новой панели; прогнать тестовый трафик через российский аналог Cloudflare параллельно с текущим решением; убедиться, что при падении базы узел уходит из ротации за отведенное время. Если эти пункты выполняются, замена Cloudflare перестает быть рискованным проектом и становится плановой задачей для ИТ-инфраструктуры.

Тестирование и мониторинг: как убедиться, что health-check работает корректно

Настроенный health-check без проверки – это вера, а не инженерия. Убедиться, что балансировщик действительно перестаёт слать трафик на узел с упавшей БД, можно только имитацией отказа и анализом того, что происходит дальше. Ниже – чек-лист, который стоит прогнать до вывода конфигурации в продакшен.

Как проверить health-check: имитация, логи, алерты

Начните с контролируемого падения БД на одном узле из пула. Не трогайте весь кластер: остановите сервис на одной ноде командой вида systemctl stop postgresql или заблокируйте порт 5432 через iptables. Дальше смотрите на три вещи одновременно.

  1. Через сколько секунд балансировщик исключил узел из ротации. Ожидаемое время = интервал проверки, умноженный на порог ошибок (например, 5 секунд x 3 = 15 секунд). Если узел остаётся в пуле дольше – пересматривайте таймауты.
  2. Куда пошли запросы. Убедитесь, что клиенты получают ответ от живых нод, а не 502/503. Полезно гонять curl в цикле с флагом –resolve и логировать HTTP-код.
  3. Что вернул сам эндпоинт. Запрос к /health на упавшем узле должен отдавать 503, а не 200 с телом про недоступную БД. Если отдаёт 200 – балансировщик не поймёт сигнал.

После восстановления БД проверьте обратное: узел должен вернуться в ротацию не мгновенно, а после N успешных проверок подряд. Резкий возврат под нагрузку часто добивает только что поднятую базу.

Логи – второй источник правды. Смотрите access-лог балансировщика: там видно, с какой периодичностью шли пробы, какие коды возвращались и когда узел помечался как down. В логах приложения ищите всплеск ошибок соединения с БД в момент, предшествующий исключению ноды. Если всплеска нет – health-check, скорее всего, проверяет не то, что нужно.

Метрики и алерты замыкают контур. Минимальный набор: доля узлов в статусе down, время реакции балансировщика на отказ, количество 5xx на выходе, задержка health-эндпоинта. Алерт стоит ставить не на сам факт падения БД (это уже авария), а на расхождение: узел отвечает 200 на health, но доля ошибок БД растёт. Это признак, что проверка недостаточно глубокая.

Отдельно проверьте поведение при частичной деградации: БД отвечает, но медленно. Установите таймаут health-эндпоинта в 2-3 секунды и добавьте в него запрос вида SELECT 1 с ограничением по времени. Если проба висит дольше таймаута – узел должен уходить из ротации так же, как при полном отказе.

Прогоняйте этот сценарий регулярно, а не один раз при настройке. Конфигурация, проверенная полгода назад, ничего не говорит о текущем состоянии инфраструктуры.

Практический шаг, который стоит сделать прямо сейчас: возьмите один узел в тестовом окружении, отключите на нем доступ к БД (закройте порт 3306 или 5432 через firewall, не трогая сервис) и посмотрите, что произойдет. Если балансировщик через 3-5 неудачных проверок вывел узел из ротации, а клиенты не увидели ошибок 5xx, схема настроена верно. Если трафик продолжает идти на узел с отвалившейся базой, вернитесь к шагу с эндпоинтом: скорее всего, он возвращает 200 при любом ответе веб-сервера. Зафиксируйте результат в чек-листе: адрес эндпоинта, интервал 5-10 секунд, таймаут 2-3 секунды, порог 3 ошибки, время возврата в строй 30-60 секунд после восстановления БД. Дальше настройте алерт на событие « узел выведен из ротации » в Telegram или почту, иначе о падении вы узнаете от клиентов.

Отдельно проверьте, как ведет себя health-check под нагрузкой. При 500 RPS проверка каждые 5 секунд с 10 узлов дает лишние 2 запроса в секунду к базе, и если эндпоинт делает тяжелый SELECT, вы получите обратный эффект: проверка сама нагружает БД и роняет ее. Ограничьтесь легким запросом вида SELECT 1 или проверкой пула соединений. Если сайт работает на WordPress, Bitrix или собственном интернет-магазине, где конверсия и лидогенерация зависят от стабильности, продублируйте проверку на уровне reverse proxy и DNS-сервиса. Российские аналоги Cloudflare, включая TrafficVeil, закрывают эту задачу вместе с L7 DDoS, защитой от ботов, GeoIP-фильтрацией и WAF, поэтому health-check, балансировка и облачная защита настраиваются в одном контуре без зависимости от зарубежной инфраструктуры.

Votre seul et unique interlocuteur : PASCAL HAGGAI