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

При задержке запроса в цепочке из пяти сервисов один график загрузки CPU не покажет, где потерялись 800 мс: в очереди, базе данных, внешнем API или повторной попытке. Наблюдаемость добавляет к системе не только дашборды, но и новый слой архитектуры — контекст запроса, правила сбора данных, хранилища, ограничения доступа и бюджет на передачу телеметрии.
Наблюдаемость — это не третий дашборд
Мониторинг отвечает на вопрос «что сломалось»: выросла задержка, закончилась память, увеличилось число ошибок. Наблюдаемость помогает ответить на вопрос «почему это произошло» по внешним данным системы, не добавляя отдельную проверку для каждого внутреннего состояния.
Обычно речь идёт о трёх сигналах:
- Метрики показывают агрегированное состояние: количество запросов, ошибки, задержки, загрузку ресурсов.
- Логи фиксируют события и детали: идентификатор заказа, результат обращения к платежному сервису, текст исключения.
- Трассировки связывают один запрос между сервисами и показывают длительность отдельных операций.
OpenTelemetry объединяет сбор и передачу этих сигналов, но не заменяет хранилище и интерфейс анализа. В конкретной архитектуре это означает дополнительные SDK или агенты, сетевые экспортеры, очереди, коллекторы и политики хранения.
Кардинальность1 — число уникальных значений атрибута. Для observability опасны поля вроде user_id, полного URL с параметрами и случайного идентификатора: они быстро увеличивают объём данных и стоимость индексации.
Главный архитектурный вопрос звучит не «какой инструмент поставить», а «какую причину сбоя мы обязуемся доказать по данным системы».
Что меняется в архитектуре
1. Запрос получает сквозной контекст
Чтобы связать лог API-шлюза с вызовом базы и удалённого сервиса, системе нужен единый идентификатор трассы. Он должен передаваться через HTTP, очередь сообщений и фоновые задачи. Если один компонент теряет этот контекст, расследование снова превращается в поиск по времени и приблизительным признакам.
Для HTTP-сервисов обычно используют формат W3C Trace Context. Но его недостаточно просто включить на входе: нужно проверить исходящие запросы, обработчики очередей, ретраи и переход в асинхронный воркер.
2. Границы сервисов становятся видимыми
Трасса показывает не только код приложения, но и реальные зависимости. Сервис, который считался самостоятельным, может синхронно ждать базу, Redis, платёжный шлюз и ещё один внутренний API. Такая схема получает несколько точек отказа и увеличивает хвост задержки: время пользовательского запроса начинает зависеть от самой медленной операции в цепочке.
После внедрения трассировки команды часто обнаруживают, что разделение на микросервисы не убрало связанность, а спрятало её за сетевыми вызовами. Это архитектурный сигнал, а не проблема интерфейса мониторинга.
3. Телеметрия становится отдельным потоком данных
Приложение теперь отправляет не только бизнес-запросы. Оно создаёт события, метрики и spans, передаёт их коллектору, а тот — в одно или несколько хранилищ. У этого потока есть собственные задержки, ошибки доставки, очереди и лимиты.
Нельзя бездумно отправлять телеметрию синхронно в критическом пути. Если внешний сборщик недоступен, пользовательский запрос не должен из-за этого получить ошибку. Для этого применяют буферизацию, пакетную отправку, ограничение размера очереди и режим сброса данных при переполнении. Но каждый механизм добавляет память, фоновые потоки и сценарии потери данных.
Четыре архитектурных подхода
| Подход | Что получаете | Цена и риск | Когда выбирать |
|---|---|---|---|
| Логи с единым trace_id | Быстрый старт и поиск связанных событий | Нет полной картины задержек; большие объёмы неструктурированных данных | Монолит или небольшое число сервисов |
| Метрики плюс логи | Алерты по состоянию и детали конкретной ошибки | Связь между сигналами требует дисциплины полей и времени | Стабильная система с понятными SLO |
| Трассировки на каждом запросе | Полная карта вызовов и задержек | Рост объёма данных, стоимость хранения, риск утечки параметров | Много синхронных зависимостей и сложные инциденты |
| Выборка трассировок | Контроль бюджета при сохранении части диагностических данных | Обычные запросы могут не попасть в выборку; правила сложнее | Высокая нагрузка и предсказуемый объём хранилища |
Выборка бывает вероятностной — например, сохраняется доля всех трасс, — и условной: система оставляет ошибки, медленные запросы или операции с определёнными признаками. Для расследований полезнее второй вариант, но он требует определить, что считать ошибкой и как долго ждать завершения трассы перед принятием решения.
Цена решения: данные, производительность и доступ
Объём нельзя оценивать только по числу серверов
Расход зависит от количества запросов, числа spans на запрос, размера атрибутов, доли выборки и срока хранения. Лог с телом HTTP-запроса может быть во много раз тяжелее метрики с несколькими измерениями. Точные цифры нужно получить нагрузочным тестом и пилотом на реальном профиле трафика, а не переносить из чужого калькулятора.
Перед внедрением измерьте:
- объём телеметрии в байтах на один пользовательский запрос;
- долю сохранённых трассировок и среднее число spans в каждой;
- добавленную задержку и потребление CPU и памяти на приложении;
- размер очереди у коллектора при недоступном хранилище;
- время поиска одной ошибки от алерта до первой подтверждённой причины.
Последний показатель важнее числа красивых графиков. Если данных стало больше, но инженер по-прежнему час ищет нужный запрос вручную, архитектура наблюдаемости не достигла цели.
Безопасность меняет схему сбора
В логи и атрибуты легко попадают токены, cookie, адреса электронной почты, номера заказов и содержимое запросов. Маскирование должно происходить до отправки в централизованное хранилище, а не только на экране дашборда. Иначе исходная копия уже окажется у коллектора или в очереди.
Разделяйте доступ к техническим метрикам, логам и трассировкам. Для отладки платежного сценария инженеру может быть нужен trace_id, но не полный ответ платёжного провайдера. Срок хранения также задаётся по типу данных: сырые события обычно не должны жить столько же, сколько агрегированные показатели.
Что ломается первым
Потеря контекста на асинхронной границе
HTTP-цепочка выглядит связной, а после публикации сообщения в брокер trace_id исчезает. В результате пользовательский запрос и обработчик очереди оказываются в разных расследованиях. Проверяйте не только библиотеку клиента, но и формат заголовков сообщения, повторную доставку и создание новой фоновой задачи.
Высокая кардинальность
Атрибут с уникальным идентификатором полезен в трассировке, но может быть разрушителен для метрик. Если записывать user_id как отдельное измерение, число временных рядов растёт вместе с аудиторией. Идентификаторы оставляйте в деталях события, а для метрик используйте ограниченный набор значений: endpoint, код результата, тип операции.
Несовместимые имена
Одна команда называет операцию checkout, другая — create_order, третья пишет полный URL. Сводные графики становятся неполными, а сравнение сервисов — спорным. Зафиксируйте словарь атрибутов и семантические соглашения OpenTelemetry, затем проверяйте их на ревью и в автоматических тестах телеметрии.
Алерт без контекста
Оповещение «ошибки выше порога» не говорит, затронуты ли пользователи и какая зависимость виновата. Алерт должен вести к метрике, примерам трасс и логам с тем же набором идентификаторов. Иначе наблюдаемость лишь ускоряет получение плохой новости.
Где подход ломается
Наблюдаемость не восстановит данные, которые приложение никогда не записало. Она также не докажет причину, если все сервисы используют разные часы, не передают контекст или скрывают ошибки за универсальным ответом 500.
Полная выборка трассировок не всегда лучше частичной. При большом трафике она может перегрузить сеть и хранилище, после чего команда отключит сбор именно во время инцидента. Слишком агрессивная фильтрация создаёт обратную проблему: редкий сбой исчезает из данных.
Для систем с жёсткими требованиями к задержке нельзя добавлять тяжёлую инструментализацию без отдельного теста. Сравнивайте контрольный прогон и прогон с телеметрией на том же железе, объёме данных и уровне параллельности. Если замеров нет, утверждение о «незаметных» накладных расходах остаётся предположением.
Что делать дальше
- Опишите три критических пользовательских сценария и их границы: вход, оформление заказа, выдача отчёта.
- Назначьте обязательные поля: trace_id, имя операции, результат, длительность и версия сервиса.
- Проверьте прохождение контекста через HTTP, брокер сообщений, ретраи и фоновые задачи.
- Запустите пилот на одном сценарии и измерьте объём телеметрии, накладные расходы и время поиска причины.
- После пилота задайте правила выборки, маскирования, доступа и хранения отдельно для логов, метрик и трассировок.
Следующий полезный шаг — не покупка нового интерфейса, а разбор одного реального инцидента по сквозной трассе. Если команда не может восстановить путь запроса и назвать потерянный контекст, исправлять нужно архитектуру сбора, а не цвет дашборда.
Логотип и фирменный стиль: Три концепции разного характера, палитра с обоснованием, проверка на читаемость в малом размере и в один цвет.
Спросить за 60 ₽Источники: OpenTelemetry: Observability primer, W3C Trace Context
Частые вопросы
Нужно ли внедрять логи, метрики и трассировки одновременно?
Может ли observability замедлить приложение?
Как не отправить в хранилище пароли и токены?
Что делать, если трассировка обрывается после очереди сообщений?
Нужна ли полная выборка трассировок для продакшена?
Какие метрики показывают, что система наблюдаемости работает?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.