Современные веб-приложения всё чаще строятся по микросервисной архитектуре. Это даёт гибкость, масштабируемость и изоляцию компонент, но одновременно усложняет отладку, мониторинг и понимание работы системы в целом. Что, если один из сервисов начинает работать медленнее? Как понять, где в цепочке запросов «узкое место»? Как быстро определить причину сбоя или деградации производительности?
Здесь на сцену выходит концепция наблюдаемости (observability). Идея заключается в том, чтобы собрать метрики, логи и трассировки из всех компонентов системы, связать их воедино, и получить чёткую картину того, что происходит внутри распределённого приложения. Для этого существуют современные инструменты вроде:
-
OpenTelemetry — открытая спецификация и набор SDK/агентов для сбора телеметрии (метрик, логов, трассировок).
-
Jaeger — платформа для распределённого трейсинга (прослеживания запросов сквозь множество сервисов).
-
Prometheus — система мониторинга и сбора метрик, ставшая де-факто стандартом в мире Kubernetes и облачных сред.
В этой статье мы шаг за шагом рассмотрим, как объединить эти инструменты, чтобы вы могли получить наглядное представление о поведении вашего микросервисного приложения, улучшить диагностику проблем и сократить время реагирования на инциденты.
Что такое наблюдаемость и зачем она нужна
Наблюдаемость — это способность системы предоставлять достаточно информации, чтобы понять её внутреннее состояние, не внося дополнительных изменений в код в момент исследования проблемы. Если раньше для отладки хватало логов, то в современных распределённых системах логи нужно дополнять метриками (измерениями производительности), трассировками (путями прохода запросов) и событиями.
Три столпа наблюдаемости:
-
Логи: Человеко-читаемые записи событий. Они дают локальную информацию о том, что произошло внутри конкретного сервиса.
-
Метрики: Числовые показатели (например, время ответа, количество запросов, использование памяти) по которым можно судить о производительности и состоянии системы.
-
Трассировки: Подробный путь запроса через систему, включая длительность отдельных этапов и вызовов. Это ключ к пониманию того, где именно «застревает» запрос.
Комбинация этих данных позволяет быстро локализовать проблемный узел, понять причину деградации или сбоя, а затем оперативно всё исправить.
Краткий обзор инструментов
OpenTelemetry (OTel):
OpenTelemetry — это открытой стандарт, цель которого — единообразно собирать телеметрию из приложений. OTel поддерживает множество языков и фреймворков, позволяя вам использовать единый подход к сбору данных. Когда вы интегрируете OTel SDK в свой код, приложение начинает экспортировать метрики, логи и трассировки.
Jaeger:
Jaeger — это система для распределённого трейсинга от CNCF. Она отлично интегрируется с OpenTelemetry. Трассировки, собранные OTel SDK, можно пересылать в Jaeger для визуализации и анализа. Вы сможете видеть цепочку вызовов микросервисов и измерять время выполнения каждой операции.
Prometheus:
Prometheus — это система мониторинга и сбора метрик с собственным форматом экспозиции данных (Pull-модель). Многие библиотеки OpenTelemetry умеют экспортировать метрики в формат, удобный для Prometheus. Собрав метрики с ваших микросервисов, вы сможете строить графики, настраивать алерты и отслеживать тенденции.
Архитектура решения
Допустим, у вас есть несколько микросервисов (на Go, Java или Node.js — не важно), каждый из которых:
-
Интегрирован с OpenTelemetry SDK.
-
Экспортирует трассировки в OpenTelemetry Collector, который затем передаёт их в Jaeger для визуализации.
-
Экспортирует метрики в формате, понятном Prometheus, который их периодически «забирает» (scrape).
Поток данных выглядит примерно так:
Микросервис -> OTel SDK -> OTel Collector -> Jaeger (для трассировок) \ -> Prometheus (для метрик)
Практический пример на Node.js
Рассмотрим простой пример на Node.js. Предположим, у нас есть микросервис orders-service
, обрабатывающий запросы заказов. Мы хотим собирать трассировки и метрики при помощи OpenTelemetry, визуализировать трассировки в Jaeger и метрики в Prometheus.
Установка зависимостей
npm install @opentelemetry/api @opentelemetry/sdk-node \ @opentelemetry/sdk-trace-node @opentelemetry/sdk-metrics \ @opentelemetry/exporter-trace-otlp-grpc @opentelemetry/exporter-metrics-prometheus \ @opentelemetry/auto-instrumentations-node
Инициализация OpenTelemetry в коде
Создадим файл tracing.js
:
// tracing.js const { NodeSDK } = require('@opentelemetry/sdk-node'); const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node'); const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc'); const { PrometheusExporter } = require('@opentelemetry/exporter-metrics-prometheus'); const { Resource } = require('@opentelemetry/resources'); const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions'); // Настраиваем экспортер трассировок в OTLP формате (коллектор) const traceExporter = new OTLPTraceExporter({ url: 'http://localhost:4317', // адрес OTel Collector }); // Настраиваем экспортер метрик для Prometheus const metricsExporter = new PrometheusExporter({ port: 9464, // порт на котором будет доступен endpoint /metrics }, () => { console.log('Prometheus scrape endpoint: http://localhost:9464/metrics'); }); // Ресурс - информация о сервисе const resource = new Resource({ [SemanticResourceAttributes.SERVICE_NAME]: 'orders-service', }); // Создаём и запускаем SDK const sdk = new NodeSDK({ traceExporter, metricExporter: metricsExporter, instrumentations: [getNodeAutoInstrumentations()], resource }); sdk.start() .then(() => console.log('OpenTelemetry started')) .catch((error) => console.log('Error starting OpenTelemetry', error)); process.on('SIGTERM', () => { sdk.shutdown() .then(() => console.log('OpenTelemetry shutdown')) .catch((error) => console.log('Error shutting down OTel', error)); });
Использование в основном приложении
Создадим файл app.js
:
// app.js require('./tracing'); // Инициализируем сбор телеметрии const express = require('express'); const app = express(); app.get('/order', (req, res) => { // Симулируем обработку заказа setTimeout(() => { res.json({ status: 'ok', orderId: 12345 }); }, 200); // задержка 200мс }); app.listen(3000, () => { console.log('Order service running on http://localhost:3000'); });
Запуская node app.js
, вы получите сервис на порте 3000, метрики на :9464/metrics
и трассировки, отправляемые в OTLP Collector.
Настройка OpenTelemetry Collector
OTel Collector — отдельный бинарник, который вы можете скачать с GitHub или использовать в Docker-контейнере. Его конфигурация YAML определяет, куда отправлять трассировки. Например:
receivers: otlp: protocols: grpc: exporters: jaeger: endpoint: "http://jaeger:14250" # адрес Jaeger (например, в Docker-сети) tls: insecure: true processors: batch: service: pipelines: traces: receivers: [otlp] processors: [batch] exporters: [jaeger]
При запуске Jaeger (через Docker, например docker run -d --name jaeger -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 -p 16686:16686 jaegertracing/all-in-one:latest
), вы сможете открыть интерфейс Jaeger по адресу http://localhost:16686
и искать трассировки от вашего orders-service
.
Настройка Prometheus
Prometheus можно запустить также в Docker:
docker run -d --name prometheus -p 9090:9090 \ -v $PWD/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus
А в файле prometheus.yml
добавить таргет на ваш сервис:
scrape_configs: - job_name: 'orders-service' static_configs: - targets: ['host.docker.internal:9464'] # если запускается локально на хосте
Теперь метрики будут доступны Prometheus, и вы сможете видеть графики, строить запросы и настраивать алерты.
Практические советы
-
Локальное окружение: Начните с запуска Jaeger, Prometheus и OTel Collector локально в Docker, тестируйте приложение у себя.
-
Инструментация кода: Используйте автоинструментацию OTel и дополнительные плагины для вашего фреймворка (Express, gRPC и т.п.).
-
Метрики производительности: Обращайте внимание на такие метрики как latency запросов, количество успешных/неуспешных ответов, использование CPU и памяти.
-
Алертинг: Добавьте Alertmanager (компонент из экосистемы Prometheus) для отправки уведомлений при достижении критических значений метрик.
-
Продакшен и безопасность: В продакшене настройте доступ к метрикам и трассировкам, используйте аутентификацию и шифрование, если необходимо.
Заключение
Внедрение наблюдаемости в микросервисное приложение — важный шаг к повышению его надёжности и управляемости. Используя OpenTelemetry в качестве единого слоя сбора телеметрии, Jaeger для распределённого трейсинга и Prometheus для метрик, вы получите всесторонний взгляд на состояние вашей системы.
Наблюдаемость не только упрощает отладку проблем, но и помогает принимать обоснованные решения: где оптимизировать код, какие сервисы масштабировать, какие запросы кешировать. Итог — более стабильный, предсказуемый и удобный в сопровождении продукт.
Попробуйте сами настроить данный стек инструментов и посмотрите, насколько проще станет диагностика проблем в вашей микросервисной архитектуре.
ссылка на оригинал статьи https://habr.com/ru/articles/865288/
Добавить комментарий