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 инициатором соединения всегда выступает агент, установленный на целевом сервере.
Механизм работы:
Преимущества Push-модели:
Недостатки Push-модели:
Pull-модель (Активный сервер)
В модели Pull инициатором соединения выступает центральный сервер мониторинга (яркий представитель — Prometheus). Агенты (экспортеры) пассивно собирают метрики и открывают локальный HTTP-сервер, ожидая запросов.
Механизм работы:
/metrics каждого агента.!Процесс сбора метрик в Pull-архитектуре
Преимущества Pull-модели:
up == 0.curl http://target-ip:9100/metrics со своего ноутбука и увидеть ровно те же данные, которые видит сервер мониторинга. Это радикально упрощает траблшутинг.Недостатки Pull-модели:
Анатомия метрик: типы данных
Для эффективного сбора и хранения все метрики классифицируются по типам поведения. Понимание этих типов критично для правильного написания запросов и генерации алертов.
Счетчик (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 архитектурами определяет топологию сети и правила безопасности, а понимание разницы между счетчиками и датчиками закладывает фундамент для точного математического анализа инцидентов.