Почему наблюдаемость критична для микросервисов
Микросервисная архитектура дарит гибкость и масштабируемость, но усложняет жизнь при отладке. Когда запрос проходит через дюжину сервисов, найти источник проблемы становится как искать иголку в стоге сена. Вот здесь и нужна наблюдаемость — способность системы раскрыть своё внутреннее состояние без изменений в коде.
Три столпа наблюдаемости
Информация о системе строится на трёх основаниях:
- Логи — события, что произошло в каждом сервисе. Локальная информация, но нужна для контекста.
- Метрики — числовые показатели (время ответа, количество запросов, память). На них строишь графики и алерты.
- Трассировки — путь запроса через систему с временем на каждом этапе. Это твой GPS для поиска узких мест.
Когда эти три источника работают вместе, диагностика инцидентов становится точной и быстрой.
Инструменты в составе
OpenTelemetry — открытая спецификация и SDK для единообразного сбора телеметрии. Поддерживает кучу языков, так что ты можешь применить один подход ко всей инфраструктуре.
Jaeger — специалист по распределённому трейсингу от CNCF. Берёт трассировки от OpenTelemetry и показывает красивую визуализацию цепочки вызовов с временем каждой операции.
Prometheus — де-факто стандарт для сбора метрик в мире облака и Kubernetes. Работает по pull-модели: сам забирает метрики с твоих сервисов.
Архитектура потока данных
Типичный сценарий выглядит так:
Микросервис
↓ (OTel SDK)
OpenTelemetry Collector
↓ ↓
Jaeger Prometheus
(трассировки) (метрики)
Каждый сервис интегрирован с OTel SDK, который экспортирует данные в Collector. Тот маршрутизирует трассировки в Jaeger, а метрики в Prometheus.
Практический старт на Node.js
Рассмотрим простой пример: микросервис orders-service, обрабатывающий заказы.
Установка зависимостей
Постави нужные пакеты:
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 для настройки SDK:
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');
// Сервис определит себя как orders-service
const resource = Resource.default().merge(
new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: 'orders-service',
}),
);
// Экспортер для трассировок (отправляет в Jaeger через OTLP)
const traceExporter = new OTLPTraceExporter({
url: 'http://localhost:4317', // gRPC endpoint Collector
});
// Экспортер для метрик (Prometheus)
const prometheusExporter = new PrometheusExporter(
{ endpoint: 'localhost:8888', path: '/metrics' },
() => {
console.log('Prometheus metrics server started at http://localhost:8888/metrics');
},
);
// Инициализируем SDK
const sdk = new NodeSDK({
resource,
traceExporter,
metricReader: prometheusExporter,
instrumentations: [getNodeAutoInstrumentations()],
});
sdl.start();
console.log('OpenTelemetry initialized');
// Graceful shutdown
process.on('SIGTERM', () => {
sdk.shutdown()
.then(() => console.log('OpenTelemetry shutdown'))
.catch((err) => console.log('OpenTelemetry shutdown error', err))
.finally(() => process.exit(0));
});
Загружай этот файл в самом начале приложения (до всех остальных модулей).
Настройка Jaeger и Prometheus
Для локального тестирования используй Docker Compose:
version: '3'
services:
jaeger:
image: jaegertracing/all-in-one:latest
ports:
- "6831:6831/udp"
- "16686:16686"
environment:
COLLECTOR_OTLP_ENABLED: 'true'
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
Теперь твоё приложение будет отправлять:
- Трассировки в Jaeger (видны по адресу
http://localhost:16686) - Метрики в Prometheus (доступны на
http://localhost:8888/metrics)
Что дальше
Объединение OpenTelemetry, Jaeger и Prometheus превращает микросервисное приложение в прозрачную систему. Ты видишь, где запрос «застревает», сколько времени уходит на каждый вызов, и как нагружены ресурсы. Это окупается многократно при первой же критической задержке в продакшене 🦆