Мониторинг и наблюдаемость — не синонимы
Мониторинг отвечает на заранее заданные вопросы: жив ли сервис, не превышен ли порог CPU, сколько ошибок за минуту. Дашборды и алерты строят под известные заранее режимы отказа — известные неизвестные.
Наблюдаемость — свойство системы, позволяющее по её внешним сигналам ответить на вопрос, который вы не задавали заранее. «Почему у пользователей из одного региона на конкретной версии клиента растёт задержка только для платных тарифов» — такой запрос нельзя предусмотреть дашбордом, его нужно уметь собрать на лету.
Отсюда практическое следствие, которое отличает содержательный ответ: наблюдаемость требует данных высокой кардинальности и возможности произвольно по ним резать. Метрика «средняя задержка» не даст ответа никогда — нужны атрибуты запроса (регион, тариф, версия) и способность группировать по ним.
В распределённой системе наблюдаемость перестаёт быть приятным дополнением. В монолите падение локализуется стектрейсом; в цепочке из пяти сервисов без корреляции запросов найти причину практически невозможно.
Три сигнала и их разделение труда
Логи — дискретные записи о событиях. Сильны в деталях: что именно произошло с конкретным запросом. Слабы в агрегации и дороги в хранении. Требование к ним одно, и оно нефункциональное: структурированность. Строка «Order failed» бесполезна, JSON с полями order_id, user_id, error_code и trace_id — искомый инструмент. Обязателен correlation id, протянутый через все сервисы.
Метрики — числовые агрегаты по времени. Дёшевы, компактны, годятся для алертов и трендов, но принципиально теряют индивидуальность запроса: по метрике нельзя узнать, что случилось с конкретным заказом. Основные типы: counter (только растёт — число запросов), gauge (произвольно колеблется — размер очереди, использование памяти), histogram (распределение по корзинам, из которого считают перцентили).
Трассировка — путь одного запроса через сервисы. Трейс состоит из спанов, у каждого свой родитель, длительность и атрибуты. Это единственный сигнал, отвечающий на вопрос «где именно ушло время» в распределённом сценарии. Контекст передаётся заголовком в стандарте W3C traceparent.
Три сигнала дополняют друг друга и связываются через идентификаторы: по алерту на метрике переходят в трейс медленного запроса, из спана — в логи с тем же trace_id. Если эта навигация не работает, у вас три несвязанных инструмента, а не наблюдаемость. Отраслевой стандарт сбора — OpenTelemetry: единый SDK и протокол для всех трёх сигналов, не привязанные к конкретному вендору.
Что измерять: RED, USE и золотые сигналы
Чтобы не изобретать набор метрик заново для каждого сервиса, пользуются готовыми схемами.
RED — для сервисов, обрабатывающих запросы: Rate (запросов в секунду), Errors (доля неуспешных), Duration (распределение времени ответа). Три метрики на каждый эндпоинт покрывают большую часть потребностей.
USE — для ресурсов (CPU, диск, пул соединений, очередь): Utilization (насколько занят), Saturation (сколько работы стоит в очереди), Errors. Ключевой сигнал здесь — насыщение: длина очереди к пулу соединений предскажет проблему задолго до того, как утилизация упрётся в сто процентов.
Четыре золотых сигнала из практики Google SRE — задержка, трафик, ошибки, насыщение — по сути объединяют оба набора. Важная деталь оттуда: задержку успешных и неуспешных запросов считают раздельно, иначе быстрые ошибки будут улучшать вашу статистику и маскировать аварию.
Общий принцип, который стоит проговорить: измеряют то, что чувствует пользователь, а не то, что удобно снимать. Загрузка CPU сама по себе не является проблемой — проблема в выросшей задержке и ошибках.
Перцентили, среднее и кардинальность
Среднее время ответа — самая вредная метрика в мониторинге. Распределение задержек имеет длинный хвост, и среднее его прячет: при среднем в 50 мс каждый сотый пользователь может ждать три секунды. Поэтому смотрят перцентили: p50 показывает типичный опыт, p95 и p99 — опыт, который формирует жалобы. В микросервисной цепочке хвост усиливается: если страница собирается из десяти параллельных вызовов, вероятность попасть хотя бы в один медленный ответ близка к его p99, умноженному на число вызовов.
Техническая ловушка, которую любят спрашивать: перцентили нельзя усреднять. Взять p99 с каждого из десяти подов и посчитать их среднее — математически бессмысленно. Правильный путь — собирать гистограммы (распределение по корзинам), складывать корзины и считать перцентиль по суммарной гистограмме.
Главная эксплуатационная ошибка в метриках — взрыв кардинальности. Каждое уникальное сочетание значений меток порождает отдельный временной ряд. Метка со статусом ответа добавит десяток рядов; метка с user_id или с полным URL, содержащим идентификаторы, добавит миллионы и положит систему мониторинга. Правило простое: в метки идут значения из небольшого фиксированного множества (метод, код ответа, шаблон маршрута /orders/{id}), а всё уникальное — в логи и трейсы, где кардинальность как раз и нужна.
Трассировка стоит дорого, поэтому её семплируют. Head-based sampling решает в начале запроса, сохранять ли трейс (просто, но интересные редкие ошибки теряются). Tail-based sampling принимает решение после завершения, зная итог, и позволяет сохранять все ошибки и все медленные запросы, семплируя только скучный успешный трафик, — заметно полезнее, но требует буферизации.
SLI, SLO, error budget
SLI (indicator) — измеряемая величина, отражающая качество для пользователя: доля успешных запросов, доля запросов быстрее 300 мс. Формулируется как отношение хороших событий ко всем.
SLO (objective) — целевое значение SLI на окне: «99,9% запросов успешны за 30 дней». Это внутреннее инженерное обязательство. SLA — внешний договор с юридическими последствиями; его цель всегда ставят слабее SLO, чтобы у команды был запас до нарушения контракта.
Error budget — прямое следствие SLO: при цели 99,9% на месяц вы имеете право на примерно 43 минуты недоступности. Это не пожелание, а инструмент принятия решений. Бюджет не израсходован — можно выкатывать чаще и рисковать смелее. Бюджет исчерпан — релизы новых фич останавливаются, пока не восстановлена надёжность. Такое правило превращает вечный спор «фичи против стабильности» в арифметику.
Важная мысль для lead-уровня: SLO выбирают не максимальным, а достаточным. Каждая девятка стоит кратно дороже предыдущей, а пользователь чаще всего не отличит 99,9% от 99,99%, если его собственный мобильный интернет надёжен на 99%. Цель ставят от реальных ожиданий пользователя, а не от красоты числа.
Алерты
Главное правило: алертить на симптомы, а не на причины. «Выросла доля ошибок 5xx» и «пользователи ждут дольше SLO» — симптомы, они всегда значимы. «Загрузка CPU 90%» — причина, и сама по себе она может быть совершенно нормальной. Алерты на причины порождают шум и будят людей зря.
Практическая техника вокруг SLO — алерт по скорости прожигания бюджета (burn rate): сигнал приходит не когда SLO уже нарушен, а когда бюджет расходуется темпом, при котором он кончится досрочно. Обычно используют два окна: короткое ловит резкую аварию быстро, длинное — медленную деградацию без ложных срабатываний.
Усталость от алертов — реальная операционная проблема, а не метафора. Если дежурного будят десять раз за ночь и девять раз это шум, десятый настоящий алерт он тоже проигнорирует. Отсюда дисциплина: каждый алерт, поднимающий человека ночью, обязан быть срочным, действенным и сопровождаться понятной инструкцией. Всё, что не требует немедленного действия, идёт в тикет или на дашборд, а не в пейджер.
И правило, которое отличает зрелую команду: алерт, оказавшийся ложным, должен быть либо починен, либо удалён — а не молча заглушен.
Как отвечать на собеседовании
Начните с разделения мониторинга и наблюдаемости через известные и неизвестные неизвестные — это сразу задаёт уровень. Перечисляя три сигнала, обязательно скажите, что каждый умеет и чего не умеет, и что связывает их correlation id и trace id.
Держите наготове RED для сервисов и USE для ресурсов, с акцентом на насыщение как ранний предиктор. И обязательно объясните, почему среднее время ответа вредно, а перцентили нельзя усреднять — эта деталь встречается редко и запоминается.
Про кардинальность расскажите как про реальную аварию: user_id в метке кладёт систему мониторинга, уникальное место — логи и трейсы. Это признак того, что вы эксплуатировали, а не только читали.
SLI/SLO/error budget объясняйте через принятие решений: бюджет исчерпан — релизы фич останавливаются. И закончите правилом алертинга: алертим на симптомы, каждый ночной алерт обязан быть действенным, ложный алерт чинят или удаляют.