Наблюдаемость: Prometheus, Zabbix и Grafana

Глубокое погружение в современные системы мониторинга и визуализации. Вы научитесь проектировать архитектуру сбора метрик, настраивать алертинг и строить профессиональные дашборды для диагностики Linux-инфраструктуры и сервисов.

1. Философия наблюдаемости: метрики, логи и архитектура Pull vs Push

Философия наблюдаемости: метрики, логи и архитектура Pull vs Push

Пользователь сообщает, что веб-страница выдает ошибку 502 Bad Gateway. Инженер открывает консоль, проверяет сервер: ping проходит без потерь, загрузка CPU составляет стабильные 15%, оперативной памяти свободно несколько гигабайт. С точки зрения базовых системных проверок инфраструктура абсолютно здорова. Однако бизнес теряет деньги каждую минуту, потому что пул соединений Nginx с PostgreSQL исчерпан, и новые запросы отбрасываются. Эта ситуация — классическая иллюстрация разницы между простым мониторингом инфраструктуры и истинной наблюдаемостью системы.

Традиционный мониторинг отвечает на вопрос «Работает ли система?». Он оперирует бинарными состояниями и заранее известными порогами: если диск заполнен на 90% — отправить алерт. Это работа с «известными неизвестными» (known unknowns) — проблемами, которые мы ожидаем и для которых заранее настроили проверки.

Наблюдаемость (Observability) отвечает на вопрос «Почему система не работает так, как должна?». Это свойство самой системы, позволяющее понять ее внутреннее состояние по внешним выходным данным. В современных распределенных архитектурах, где запросы проходят через балансировщики, контейнеры Docker, очереди сообщений и базы данных, невозможно предсказать все варианты сбоев. Наблюдаемость позволяет расследовать «неизвестные неизвестные» (unknown unknowns) — аномалии, с которыми команда ранее не сталкивалась.

Три столпа наблюдаемости

Для реконструкции внутреннего состояния приложения инженеры опираются на три фундаментальных типа данных. Они не заменяют, а дополняют друг друга, образуя единый контекст.

Логи (Logs)

Лог — это неизменяемая, снабженная временной меткой запись о дискретном событии, произошедшем в системе.

Логи обладают высочайшей детализацией. Запись в access.log Nginx содержит IP-адрес клиента, URL, HTTP-статус, User-Agent и время ответа. Ошибка в логе PostgreSQL покажет конкретный SQL-запрос, вызвавший нарушение уникального индекса.

Главная проблема логов — их объем и стоимость обработки. Если высоконагруженный сервис генерирует 10 000 запросов в секунду, запись каждого события потребует гигабайты дискового пространства ежедневно. Поиск по неструктурированному тексту ресурсоемок. Поэтому логи идеальны для глубокого расследования (debugging) уже выявленной проблемы, но плохо подходят для оценки общего состояния системы в реальном времени.

Метрики (Metrics)

Метрика — это числовое значение, измеренное в определенный момент времени. В отличие от логов, метрики агрегируют данные.

Вместо того чтобы записывать каждый из 10 000 HTTP-запросов, система генерирует одну строку временного ряда (time-series). Структура типичной метрики включает имя, набор тегов (ключ-значение) для фильтрации, само число и timestamp: http_requests_total{method="GET", status="200"} 45192 1698745200

Метрики невероятно дешевы в хранении и передаче. Независимо от того, обрабатывает сервис 10 запросов в секунду или 100 000, объем памяти для хранения счетчика http_requests_total остается неизменным — это просто число, которое увеличивается. Метрики позволяют строить графики, вычислять производные (скорость изменения) и мгновенно оценивать здоровье системы. Именно они служат фундаментом для настройки автоматических уведомлений (алертов).

Трейсы (Traces)

Трейсинг отслеживает жизненный цикл одного конкретного запроса при его прохождении через все компоненты микросервисной архитектуры. Каждому запросу на входе присваивается уникальный Trace ID, который передается по цепочке от Nginx к backend-приложению, затем к базе данных и внешним API. Трейсы позволяют выявить узкие места производительности (например, понять, что из 2 секунд ответа пользователю 1.8 секунды занял медленный запрос к PostgreSQL).

В рамках построения базового инфраструктурного мониторинга основной фокус всегда направлен на метрики (для обнаружения проблем) и логи (для поиска причин).

| Характеристика | Метрики | Логи | | :--- | :--- | :--- | | Структура | Число + теги + время | Текст (часто JSON) + время | | Объем данных | Низкий (постоянный) | Высокий (пропорционален нагрузке) | | Скорость запросов | Мгновенно (математика) | Медленно (поиск по тексту/индексу) | | Основная задача | Алертинг, дашборды, тренды | Дебаггинг, аудит, детализация |

Архитектура сбора данных: Push против Pull

Чтобы метрики превратились в красивые графики и алерты, их нужно собрать с десятков или сотен серверов и поместить в централизованное хранилище — Time Series Database (TSDB). Исторически сложились две архитектурные модели взаимодействия между агентами (источниками данных) и сервером мониторинга: Push (выталкивание) и Pull (вытягивание).

!Сравнение архитектур Pull и Push

Push-модель (Активные агенты)

В модели Push инициатором соединения всегда выступает агент, установленный на целевом сервере.

Механизм работы:

  • Агент (например, Zabbix Agent в активном режиме или Telegraf) собирает данные локально.
  • Агент открывает сетевое соединение с центральным сервером мониторинга.
  • Агент отправляет пакет данных (payload) и закрывает соединение.
  • Преимущества Push-модели:

  • Обход NAT и строгих файрволов. Если целевой сервер находится в изолированной подсети, ему достаточно иметь разрешение на исходящий трафик (Egress) к IP-адресу сервера мониторинга. Серверу не нужно знать, как достучаться до агента.
  • Эфемерные задачи. Если скрипт резервного копирования запускается по cron, отрабатывает за 5 секунд и завершается, он может в конце своей работы отправить метрику об успехе на сервер. В Pull-модели сервер просто не успел бы его опросить.
  • Безопасность периметра. На целевых серверах не нужно открывать входящие порты для прослушивания.
  • Недостатки Push-модели:

  • Проблема «Громоздкого стада» (Thundering Herd). Если в инфраструктуре 5 000 серверов, и все агенты настроены на отправку данных ровно в начало каждой минуты, центральный сервер получит одновременный шквал соединений, что может привести к отказу в обслуживании (DDoS-эффект).
  • Сложность обнаружения сбоев. Если агент перестал присылать данные, сервер не знает причину. Сервер упал? Пропала сеть? Процесс агента завис? Для решения этой проблемы требуются дополнительные механизмы (heartbeats).
  • Сложность настройки лимитов. Центральный сервер не контролирует объем входящих данных. Некорректно настроенный агент может переполнить диск сервера мониторинга мусорными метриками.
  • Pull-модель (Активный сервер)

    В модели Pull инициатором соединения выступает центральный сервер мониторинга (яркий представитель — Prometheus). Агенты (экспортеры) пассивно собирают метрики и открывают локальный HTTP-сервер, ожидая запросов.

    Механизм работы:

  • Сервер мониторинга имеет список целей (Target list).
  • По расписанию (например, каждые 15 секунд) сервер инициирует HTTP GET запрос на эндпоинт /metrics каждого агента.
  • Агент отдает текущий снимок метрик в текстовом формате.
  • !Процесс сбора метрик в Pull-архитектуре

    Преимущества Pull-модели:

  • Централизованный контроль нагрузки. Сервер сам решает, кого и когда опрашивать. Он может размазать запросы во времени, избегая пиковых нагрузок.
  • Мгновенное обнаружение сбоев. Если HTTP-запрос к агенту завершился по таймауту или вернул ошибку, сервер точно знает, что цель недоступна, и может немедленно сгенерировать алерт up == 0.
  • Простота отладки. Любой инженер может выполнить команду curl http://target-ip:9100/metrics со своего ноутбука и увидеть ровно те же данные, которые видит сервер мониторинга. Это радикально упрощает траблшутинг.
  • Естественная интеграция с Service Discovery. В динамических средах вроде Kubernetes IP-адреса контейнеров меняются постоянно. Сервер мониторинга опрашивает API Kubernetes, получает актуальный список IP-адресов и динамически меняет список целей для опроса.
  • Недостатки Pull-модели:

  • Сетевая доступность. Сервер мониторинга должен иметь маршрут и разрешения файрвола для входящего подключения к каждому агенту (Ingress). В сложных сетях с множеством DMZ и NAT это требует тщательной настройки маршрутизации.
  • Невидимость короткоживущих процессов. Если процесс живет 2 секунды, а сервер опрашивает метрики раз в 15 секунд, процесс исчезнет до того, как его успеют опросить.
  • Анатомия метрик: типы данных

    Для эффективного сбора и хранения все метрики классифицируются по типам поведения. Понимание этих типов критично для правильного написания запросов и генерации алертов.

    Счетчик (Counter)

    Счетчик — это кумулятивная метрика, значение которой может только увеличиваться (или сбрасываться в ноль при перезапуске процесса). Примеры: общее количество обработанных HTTP-запросов, суммарное время работы процессора, количество отправленных байт.

    Само по себе текущее значение счетчика (например, 1 500 000 запросов) не несет пользы. Важна скорость его изменения во времени — рейт (rate). Математически это вычисляется как разница значений, разделенная на интервал времени:

    Где и — значения счетчика в моменты времени и . Если за 60 секунд счетчик вырос на 120, значит, система обрабатывает 2 запроса в секунду.

    Датчик (Gauge)

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

    К датчикам нельзя применять функцию вычисления скорости (rate), так как их падение не означает перезапуск или сброс — это естественное поведение. Датчики используются для оценки запаса прочности (Capacity Planning) и алертов на превышение порогов (например, memory_usage > 90%).

    Гистограмма (Histogram)

    Гистограмма используется для измерения распределения значений, чаще всего — длительности операций или размеров ответов. Вместо того чтобы хранить время выполнения каждого из тысяч запросов, гистограмма распределяет их по заранее заданным корзинам (buckets) и считает количество попаданий в каждую.

    Например, для измерения задержки (latency) веб-сервера задаются корзины: до 0.1 сек, до 0.5 сек, до 1 сек. Если запрос выполнился за 0.3 секунды, увеличивается счетчик корзины «до 0.5 сек». Это позволяет вычислять перцентили (например, 99-й перцентиль — время, быстрее которого обслуживаются 99% пользователей) и отслеживать деградацию производительности, даже если среднее время ответа выглядит нормально.

    Граничные случаи и гибридные подходы

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

    Проблема эфемерных задач в Pull-модели. Как было отмечено, Pull-сервер не может собрать метрики с процессов, которые завершаются быстрее интервала опроса. Для решения этой проблемы в экосистеме Prometheus существует компонент Pushgateway. Короткоживущий скрипт (например, бэкап базы данных) работает по Push-модели: перед завершением он отправляет (выталкивает) свои финальные метрики в Pushgateway. Сам Pushgateway работает постоянно, кэширует эти метрики и отдает их серверу Prometheus по стандартной Pull-модели при следующем опросе.

    Поведение при сетевом разделении (Network Partition). Если между сегментом сети с агентами и сервером мониторинга падает линк, модели ведут себя по-разному. В Push-модели продвинутые агенты (например, Telegraf) могут использовать локальный буфер. Они накапливают метрики в оперативной памяти или на диске агента, и после восстановления связи отправляют весь накопленный пакет, сохраняя историческую непрерывность данных. В строгой Pull-модели сервер просто фиксирует отсутствие ответа. На графиках образуются пустые разрывы (gaps). С точки зрения философии Pull это считается корректным: сервер честно фиксирует, что в этот период времени состояние системы было неизвестно.

    Наблюдаемость не возникает автоматически после установки инструмента. Это процесс проектирования системы таким образом, чтобы она сама рассказывала о своем состоянии. Выбор между Pull и Push архитектурами определяет топологию сети и правила безопасности, а понимание разницы между счетчиками и датчиками закладывает фундамент для точного математического анализа инцидентов.