Зачем нужен мониторинг upstream в Nginx
Запросы клиентов уходят на упавший бэкенд. Пользователи видят ошибки 502 или 504. Инженер узнает о проблеме от разгневанных клиентов, а не от системы мониторинга. Знакомая ситуация для любого, кто управляет высоконагруженными сервисами без должного контроля за состоянием upstream-пулов.
Nginx распределяет трафик на группу серверов через блок upstream. Без мониторинга этот механизм работает вслепую: балансировщик продолжает отправлять запросы на узел, который уже не отвечает или отвечает слишком медленно. Результат - каскадный сбой и простой сервиса.
Эта статья дает готовые решения для трех ключевых задач: автоматическое исключение проблемных бэкендов через health checks, сбор метрик доступности и времени отклика каждого сервера, визуализация данных в Grafana. Вы получите конфигурации для Nginx Plus и open-source версии, которые прошли проверку в production-среде. Если вам нужна продвинутая настройка высокой доступности Nginx, начните с этой базы.
Правильно настроенный мониторинг сокращает время обнаружения сбоя с часов до секунд. Вы увидите деградацию сервиса до того, как она станет заметна пользователям. Это не теория - это инженерная практика, которую мы разберем по шагам.
Health Checks: автоматическое отключение проблемных бэкендов
Health check - это механизм проверки работоспособности бэкенд-сервера. Nginx выполняет проверку и, если сервер не проходит тест, временно исключает его из пула. Трафик идет только на живые узлы. Когда сервер восстанавливается, балансировщик возвращает его в работу.
Есть два типа проверок: пассивные и активные. Пассивные реагируют на ошибки в реальном трафике. Активные инициативно опрашивают бэкенды по расписанию. Выбор зависит от версии Nginx и требований к скорости обнаружения сбоев.
Пассивные health checks в open-source Nginx
Open-source Nginx включает пассивные проверки через директивы max_fails и fail_timeout в блоке upstream. Механизм работает так: Nginx считает неудачные попытки соединения с бэкендом. Когда количество ошибок достигает max_fails за период fail_timeout, сервер помечается как нерабочий на этот же период.
Базовая конфигурация:
upstream backend {
server 10.0.0.1:80 max_fails=3 fail_timeout=30s;
server 10.0.0.2:80 max_fails=3 fail_timeout=30s;
server 10.0.0.3:80 max_fails=3 fail_timeout=30s;
}
server {
location / {
proxy_pass http://backend;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
}
}
Параметр max_fails=3 означает: после трех ошибок за 30 секунд сервер выводится из пула на 30 секунд. Директива proxy_next_upstream определяет, какие ошибки считаются основанием для перехода к следующему бэкенду. По умолчанию это только error и timeout - для production-среды стоит добавить http_500, http_502 и http_503.
Ограничения пассивных проверок критичны. Nginx не опрашивает бэкенды proactively - он узнает о проблеме только когда на нее натыкается реальный запрос. Если сервер завис, но соединение устанавливается, пассивная проверка может не сработать. Клиент получит таймаут, а не быстрый failover. Для высоконагруженных систем этого недостаточно.
Активные health checks в Nginx Plus
Nginx Plus решает проблему пассивных проверок директивой health_check. Балансировщик сам инициирует соединения с бэкендами по расписанию и проверяет их состояние независимо от пользовательского трафика. Упавший сервер обнаруживается за секунды, а не после первой ошибки клиента.
Минимальная конфигурация активного health check:
upstream backend {
zone backend 64k;
server 10.0.0.1:80;
server 10.0.0.2:80;
server 10.0.0.3:80;
}
server {
location / {
proxy_pass http://backend;
health_check interval=5s fails=3 passes=2;
}
}
Директива health_check принимает ключевые параметры:
- interval - частота проверок. 5 секунд подходит для большинства сценариев. Уменьшение до 1-2 секунд увеличивает нагрузку на сеть, но ускоряет обнаружение сбоя.
- fails - количество последовательных неудачных проверок для пометки сервера как нерабочего.
- passes - количество успешных проверок перед возвратом сервера в пул. Защищает от флаппинга - частого переключения статуса.
Для проверки конкретного эндпоинта используется директива match:
match health_check_status {
status 200;
header Content-Type = text/html;
body ~ "OK";
}
server {
location / {
proxy_pass http://backend;
health_check uri=/health match=health_check_status;
}
}
Этот блок проверяет, что бэкенд возвращает 200 OK, заголовок Content-Type равен text/html, а тело ответа содержит строку "OK". Такой подход выявляет не только сетевые проблемы, но и логические ошибки приложения - например, когда веб-сервер отвечает, но база данных недоступна.
Nginx Plus поддерживает mandatory health checks - постоянный мониторинг всех серверов пула независимо от того, обрабатывают ли они трафик. Это полезно для резервных узлов, которые должны быть готовы принять нагрузку в любой момент.
Активные health checks в open-source: модуль nginx_upstream_check_module
Если бюджет не позволяет приобрести Nginx Plus, активные проверки можно добавить в open-source версию через сторонний модуль nginx_upstream_check_module от Tengine (форк Nginx от Alibaba). Модуль не входит в стандартную сборку - потребуется перекомпиляция.
Установка модуля:
# Скачайте исходники Nginx и модуль
git clone https://github.com/nginx/nginx.git
cd nginx
git clone https://github.com/yaoweibin/nginx_upstream_check_module.git
# Примените патч
patch -p1 < nginx_upstream_check_module/check_1.20.1+.patch
# Соберите с модулем
./configure --add-module=./nginx_upstream_check_module
make && make install
Конфигурация после установки:
upstream backend {
server 10.0.0.1:80;
server 10.0.0.2:80;
server 10.0.0.3:80;
check interval=3000 rise=2 fall=5 timeout=1000 type=http;
check_http_send "HEAD /health HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
server {
location /status {
check_status;
allow 10.0.0.0/8;
deny all;
}
}
Параметры модуля:
- interval - интервал между проверками в миллисекундах (3000 = 3 секунды).
- rise - количество успешных проверок для возврата сервера в работу.
- fall - количество неудачных проверок для вывода сервера из пула.
- timeout - таймаут ожидания ответа.
- type - протокол проверки: http, tcp, ssl_hello, mysql, ajp.
Location /status отдает HTML-страницу с текущим состоянием всех upstream-серверов. Эту страницу можно парсить для сбора метрик или использовать для быстрой визуальной диагностики.
Модуль функционально близок к Nginx Plus, но имеет недостатки: ручная сборка усложняет обновления, нет нативной интеграции с Prometheus, сообщество меньше. Для production-сред с жесткими требованиями к надежности Nginx Plus предпочтительнее.
Сбор метрик доступности и времени отклика
Health checks отвечают на вопрос "жив ли сервер?". Метрики отвечают на вопросы "насколько сервер быстр?" и "как меняется его состояние во времени?". Без метрик вы не увидите трендов - сервер может деградировать постепенно, и пассивные проверки заметят проблему слишком поздно.
Для полноценного мониторинга upstream нужны три группы метрик: доступность (up/down статус), время отклика (latency по каждому бэкенду), количество активных соединений. Сбор этих данных зависит от версии Nginx и выбранного инструментария.
Использование ngx_http_stub_status_module
Модуль stub_status - это встроенный способ получить базовые метрики Nginx. Он доступен в open-source версии и включается при сборке флагом --with-http_stub_status_module (в большинстве дистрибутивов уже включен).
Конфигурация:
server {
listen 127.0.0.1:80;
server_name status.local;
location /nginx_status {
stub_status;
allow 127.0.0.1;
deny all;
}
}
Вывод модуля:
Active connections: 291
server accepts handled requests
16630948 16630948 31070465
Reading: 6 Writing: 179 Waiting: 106
Эти цифры показывают общую картину по всему Nginx: активные соединения, общее количество принятых и обработанных запросов, текущие операции чтения/записи. Детализации по upstream-серверам здесь нет. Stub_status полезен для мониторинга самого балансировщика, но не для контроля за бэкендами. Подробнее о практическом мониторинге Nginx с Prometheus и Grafana читайте в отдельном руководстве.
Экспорт метрик upstream через nginx-prometheus-exporter
nginx-prometheus-exporter - это официальный экспортер от NGINX Inc., который извлекает метрики из stub_status или Nginx Plus API и отдает их в формате Prometheus. Для upstream-метрик потребуется Nginx Plus, так как open-source версия не предоставляет необходимой детализации через stub_status.
Запуск экспортера:
nginx-prometheus-exporter \
-nginx.scrape-uri=http://127.0.0.1:8080/api/3/nginx \
-web.listen-address=:9113
Ключевые метрики, которые экспортер отдает для upstream:
- nginx_upstream_server_state - состояние сервера (0=down, 1=up, 2=draining). Основа для алертов о недоступности.
- nginx_upstream_server_response_time - среднее время ответа бэкенда в миллисекундах. Рост этого показателя сигнализирует о деградации.
- nginx_upstream_server_active - количество активных соединений с конкретным бэкендом. Показывает распределение нагрузки.
- nginx_upstream_server_requests - общее количество запросов к серверу. Используется для расчета доли трафика.
- nginx_upstream_server_fails - счетчик неудачных проверок health check. Помогает выявить нестабильные узлы.
Конфигурация Prometheus для сбора метрик:
scrape_configs:
- job_name: 'nginx-upstream'
scrape_interval: 15s
static_configs:
- targets: ['nginx-host:9113']
Для open-source версии альтернативой служит модуль nginx_upstream_check_module с его страницей /status. Метрики с нее можно собирать через скрипт-адаптер или использовать неофициальные экспортеры, но надежность такого решения ниже.
Метрики Nginx Plus API
Nginx Plus предоставляет REST API с детальной статистикой по каждому upstream-серверу. API включается директивой api в конфигурации:
server {
listen 8080;
location /api {
api write=off;
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
}
}
Запрос к эндпоинту /api/3/http/upstreams возвращает JSON с полной информацией:
{
"backend": {
"peers": [
{
"server": "10.0.0.1:80",
"state": "up",
"active": 12,
"requests": 145670,
"responses": {
"1xx": 0, "2xx": 145600, "3xx": 50, "4xx": 20, "5xx": 0
},
"response_time": 45,
"health_checks": {
"checks": 345600,
"fails": 0,
"unhealthy": 0
}
}
]
}
}
Этот JSON содержит готовые метрики времени отклика (response_time), распределение HTTP-кодов, статистику health checks. Nginx Plus API - самый полный источник данных для мониторинга upstream. Он не требует дополнительных модулей и работает из коробки.
Визуализация данных в Grafana
Собранные метрики превращаются в actionable информацию через дашборды Grafana. Цифры в Prometheus бесполезны, пока вы не видите графиков, таблиц и цветовых индикаторов. Хороший дашборд позволяет за 5 секунд оценить состояние всех upstream-пулов и заметить аномалию.
Базовый дашборд для мониторинга upstream
Настройка источника данных Prometheus в Grafana - стандартная операция: Connections → Data Sources → Add data source → Prometheus → укажите URL вашего Prometheus сервера.
Ключевые панели для upstream-дашборда:
Статус серверов (Stat panel):
nginx_upstream_server_state{upstream="backend"}
Эта панель показывает цветной индикатор для каждого бэкенда: зеленый - up, красный - down. Используйте Stat panel с Value options → Fields → server.
Время отклика (Time series):
rate(nginx_upstream_server_response_time_seconds_sum{upstream="backend"}[5m])
/
rate(nginx_upstream_server_response_time_seconds_count{upstream="backend"}[5m])
График показывает среднее время ответа каждого сервера за 5-минутные интервалы. Резкий рост - повод для немедленной проверки.
Сводная таблица (Table):
nginx_upstream_server_state{upstream="backend"}
and
rate(nginx_upstream_server_requests{upstream="backend"}[1m])
Таблица объединяет статус, количество запросов в минуту и время отклика по всем серверам пула. Удобно для быстрого сравнения нагрузки между узлами.
Распределение HTTP-кодов (Bar gauge):
sum by (code) (rate(nginx_upstream_server_responses{upstream="backend"}[5m]))
Показывает долю успешных ответов (2xx), клиентских (4xx) и серверных (5xx) ошибок. Рост 5xx даже на одном бэкенде требует внимания.
Настройка алертов в Grafana
Дашборд без алертов - это наблюдение задним числом. Алерты оповещают о проблеме в момент ее возникновения, а не при следующем просмотре графиков.
Правило для недоступности сервера:
nginx_upstream_server_state{upstream="backend"} == 0
Настройте условие: если метрика равна 0 дольше 60 секунд, отправлять алерт. Короткие всплески (флаппинг) отсекаются evaluation interval.
Правило для роста времени отклика:
histogram_quantile(0.95, rate(nginx_upstream_server_response_time_seconds_bucket{upstream="backend"}[5m])) > 0.5
Этот запрос срабатывает, когда 95-й перцентиль времени ответа превышает 500 миллисекунд. Порог подбирается под конкретный сервис - для API это может быть 100ms, для тяжелых страниц - 1 секунда.
Интеграция с Alertmanager позволяет маршрутизировать оповещения в Slack, Telegram, PagerDuty или email. Настройте разные каналы для критичных (сервер down) и предупредительных (рост latency) алертов.
Сравнение решений: Nginx Plus vs Open-Source
Выбор между коммерческой и бесплатной версией Nginx для мониторинга upstream сводится к трем факторам: функциональность, стоимость поддержки, критичность сервиса.
| Критерий | Nginx Plus | Open-Source + модули |
|---|---|---|
| Активные health checks | Встроенные, директива health_check | Требуется nginx_upstream_check_module и пересборка |
| API для метрик | REST API с детализацией по upstream | Страница /status от модуля, требует парсинга |
| Интеграция с Prometheus | Официальный экспортер | Сторонние адаптеры или ручной парсинг |
| Поддержка | 24/7 от NGINX Inc. | Community, документация модуля |
| Стоимость | От $2500/год за инстанс | Бесплатно (затраты на администрирование) |
| Обновления | Пакетные, без пересборки | Ручная перекомпиляция при каждом обновлении |
Open-source версии с модулем достаточно, когда: бюджет ограничен, сервис не критичен к простою в 30-60 секунд, в команде есть инженер, готовый поддерживать кастомную сборку. Для стартапов и небольших проектов это рабочее решение.
Nginx Plus оправдан, когда: сервис приносит деньги и каждый час простоя стоит дороже годовой лицензии, требуется быстрая реакция на сбои (активные проверки каждую секунду), нужна официальная поддержка. Банки, e-commerce, high-load SaaS - здесь экономия на лицензии оборачивается потерями при инцидентах.
Если вы строите отказоустойчивую инфраструктуру, посмотрите руководство по настройке отказоустойчивого API Gateway - там разобраны сценарии с автоматическим failover и кешированием.
Типовые проблемы и их решение
Внедрение мониторинга upstream редко проходит без сюрпризов. Разберем частые проблемы, с которыми сталкиваются инженеры.
Health check нагружает бэкенд. Активные проверки создают дополнительный трафик. Для 100 серверов с интервалом 1 секунда это 100 запросов в секунду. Решение: выделите легковесный эндпоинт /health, который не обращается к базе данных и не выполняет бизнес-логику. Проверяйте только факт работы веб-сервера. Увеличьте интервал до 3-5 секунд для некритичных сервисов.
Ложные срабатывания. Сервер помечается как down из-за кратковременного всплеска latency, хотя он работоспособен. Причина: слишком агрессивные настройки fails и timeout. Решение: увеличьте fails до 3-5, timeout до 2-3 секунд. Настройте параметр passes для возврата сервера - это предотвратит флаппинг.
Неправильные таймауты. Пассивный health check срабатывает слишком поздно, потому что proxy_read_timeout больше fail_timeout. Клиенты ждут ответа 60 секунд, хотя сервер уже помечен как нерабочий. Решение: синхронизируйте таймауты. fail_timeout должен быть сопоставим с proxy_connect_timeout и proxy_read_timeout.
Диагностика через логи. Когда метрики показывают проблему, но причина неясна, включайте детальное логирование upstream:
log_format upstream_info '$remote_addr - $upstream_addr - '
'$upstream_response_time - $upstream_status - '
'$upstream_connect_time';
access_log /var/log/nginx/upstream.log upstream_info;
Этот формат пишет, на какой бэкенд ушел запрос, сколько времени занял ответ и соединение. Анализ таких логов выявляет медленные узлы и неравномерность распределения нагрузки. Для автоматизации анализа используйте готовые команды grep и awk для поиска ошибок в логах Nginx.
Выбор алгоритма балансировки влияет на мониторинг. При ip_hash все запросы пользователя идут на один сервер - отказ этого сервера затрагивает конкретных пользователей, а не всех. Least_conn распределяет нагрузку по фактической загрузке. Round-robin равномерно размазывает трафик. Подробный разбор стратегий с примерами конфигураций смотрите в статье про алгоритмы балансировки Nginx.
Мониторинг Nginx upstream - это не разовая настройка, а процесс. Начните с пассивных health checks и базовых метрик. Добавьте активные проверки, когда поймете паттерны отказов. Настройте алерты, когда накопите статистику по нормальному поведению сервиса. Каждый шаг приближает инфраструктуру к состоянию, когда о проблемах вы узнаете раньше пользователей.