Отметим: когда p95 latency микросервисного API неожиданно взлетает до 10 секунд, а логи в Order Service идеально чисты — начинается охота на призрака. В таких ситуациях мы разворачиваем distributed tracing: OpenTelemetry + Jaeger (или Zipkin) для полной видимости. Подробнее о distributed tracing можно узнать в Wikipedia. Каждый запрос оставляет цифровой след через все сервисы — от API Gateway до Payment Service — с временными метками. Вы видите, что 80% времени тратится на один запрос к Elasticsearch, а не на распределённую блокировку. После внедрения клиенты сокращают время диагностики с трёх недель до двух дней — в 3 раза быстрее. Один из клиентов сэкономил $11k–16k в год за счёт сокращения простоев и быстрой локализации проблем. Другой клиент с 25 микросервисами сократил время диагностики на 70%, что привело к экономии $7.2k–10k в год.
Какие проблемы решает распределённая трассировка
Типичная ситуация: N+1 query в Inventory Service превращает ответ в 5 секунд. Или Redis кеш не работает из-за неправильного TTL — трейс покажет отсутствие кеш-хита. Distributed tracing раскрывает время в каждом сервисе, вызовы БД (PostgreSQL, MongoDB), внешних API и контекст propagation. Вы видите, что 80% времени уходит на один запрос к Elasticsearch, а не на распределённую блокировку. Мы настраиваем трассировку, чтобы выявить узкие места за часы, а не недели. Конкретный пример: для одного клиента с 15 микросервисами distributed tracing показал, что 40% запросов зависали из-за неправильного таймаута в HTTP-клиенте. Исправление заняло 2 часа вместо недели гаданий.
Почему OpenTelemetry — стандарт де-факто?
OpenTelemetry (OTel) — vendor-neutral SDK, который позволяет отправлять трейсы в любой бэкенд без смены кода. Мы используем его во всех проектах: один раз интегрировали, потом выбираем Jaeger для разработки, Datadog для прода — без переписывания. Поддержка сейчас уже 20+ языков и интеграций. По сравнению с проприетарными SDK, OpenTelemetry снижает время интеграции в 2 раза и упрощает миграцию между бэкендами. Наш опыт внедрения на десятках проектов подтверждает надёжность этого подхода.
Как внедрить OpenTelemetry в Node.js: пошаговая инструкция
- Установите пакеты:
npm install @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-otlp-http. - Создайте файл
tracing.ts(импортируйте первым). - Настройте экспортёр: укажите URL Jaeger или другого бэкенда.
- Добавьте авто-инструментации для HTTP, Express, PostgreSQL, Redis и т.д.
- Запустите SDK вызовом
sdk.start().
Пример инициализации для Order Service:
// tracing.ts — инициализация, импортировать до всего остального import { NodeSDK } from '@opentelemetry/sdk-node'; import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; import { Resource } from '@opentelemetry/resources'; import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions'; const sdk = new NodeSDK({ resource: new Resource({ [SEMRESATTRS_SERVICE_NAME]: 'order-service', }), traceExporter: new OTLPTraceExporter({ url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://jaeger:4318/v1/traces', }), instrumentations: [ getNodeAutoInstrumentations({ '@opentelemetry/instrumentation-http': { enabled: true }, '@opentelemetry/instrumentation-express': { enabled: true }, '@opentelemetry/instrumentation-pg': { enabled: true }, '@opentelemetry/instrumentation-redis': { enabled: true }, }), ], }); sdk.start(); Авто-инструментации перехватывают Express, pg, redis, axios без написания кода.
Ручное создание спанов
Для бизнес-операций, которые не перехватываются авто-инструментацией:
import { trace, SpanStatusCode, context } from '@opentelemetry/api'; const tracer = trace.getTracer('order-service'); async function processOrder(orderId: string): Promise<void> { const span = tracer.startSpan('processOrder', { attributes: { 'order.id': orderId, 'service.operation': 'process' } }); try { await context.with(trace.setSpan(context.active(), span), async () => { const order = await loadOrder(orderId); // дочерний span создаётся авто await validateOrder(order); await reserveInventory(order); // вызов другого сервиса с propagation await chargePayment(order); }); span.setStatus({ code: SpanStatusCode.OK }); } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error.message }); throw error; } finally { span.end(); } } Как выбрать бэкенд: Jaeger или Zipkin?
| Zipkin | Jaeger | |
|---|---|---|
| Хранилище | MySQL, Elasticsearch, Cassandra | Elasticsearch, Cassandra, Kafka |
| UI | Базовый | Более богатый |
| OTel поддержка | Есть | Нативная |
| Sampling | Базовое | Расширенное |
Для новых проектов — Jaeger. Zipkin — если уже используется или нужна совместимость. Jaeger в среднем в 1.5–2 раза быстрее разворачивается и предоставляет более детальные дашборды. Мы гарантируем, что выбранный бэкенд будет оптимально интегрирован в вашу инфраструктуру.
Как настроить sampling под нагрузку?
OpenTelemetry Specification рекомендует head-based sampling для высоконагруженных систем.
| Стратегия | Процент захвата | Ресурсы | Когда применять |
|---|---|---|---|
| Head-based (с вероятностью) | 1–10% | Низкие | Высоконагруженные системы с большим объёмом трейсов |
| Tail-based | 100% с фильтрацией | Высокие | Нужны все трейсы с ошибками, редкие события |
Пример конфигурации head-based sampling с OpenTelemetry:
import { ParentBasedSampler, TraceIdRatioBased } from '@opentelemetry/sdk-trace-base'; const sampler = new ParentBasedSampler({ root: new TraceIdRatioBased(0.1) }); Так вы трейсите 10% запросов, но всегда — если родительский уже трейсится.
Пример конфигурации tail-based sampling с OpenTelemetry Collector
Tail-based sampling требует OpenTelemetry Collector с функцией tail_sampling. Конфигурация:
processors: tail_sampling: decision_wait: 30s num_traces: 100 expected_new_traces_per_sec: 10 policies: - name: sample_errors type: status_code properties: status_codes: [ERROR] - name: sample_slow type: latency properties: threshold_ms: 500 Что входит в работу по настройке трассировки?
Мы предоставляем:
- Выбор и развёртывание бэкенда (Jaeger/Zipkin) с хранилищем (Elasticsearch/Cassandra)
- Интеграция OpenTelemetry SDK с авто-инструментациями для всех сервисов
- Ручное инструментирование критических бизнес-операций
- Настройка контекстного распространения через HTTP-заголовки (W3C Trace Context)
- Конфигурирование sampling под нагрузку
- Документация по эксплуатации и дашборды в Grafana
- Обучение команды работе с трейсами
Сроки ориентировочно
- OpenTelemetry SDK + Jaeger + авто-инструментации для 3–5 сервисов — 3–5 дней
- Ручное инструментирование бизнес-операций + настройка sampling — ещё 3–5 дней
- Настройка алертов на p95 latency через Prometheus + Grafana — 2–3 дня
Получите консультацию инженера — мы поможем выбрать оптимальный бэкенд и настроить трассировку под вашу архитектуру. Закажите трассировку под ключ — и вы получите полную картину работы микросервисов. Свяжитесь с нами, чтобы оценить ваш проект и узнать, как distributed tracing сократит время отладки в вашей системе.







