Что такое distributed tracing?
Distributed tracing (распределённая трассировка) — метод отслеживания прохождения запроса через множество сервисов в распределённой системе. Каждый запрос получает уникальный идентификатор (traceId), который передаётся между сервисами, позволяя восстановить полную картину обработки.
Зачем нужен distributed tracing
В микросервисной архитектуре один пользовательский запрос может вызвать цепочку вызовов:
Пример
Пользователь → API Gateway → Order Service → Payment Service → Notification Service
│ │
└── Inventory Service └── Email Service
│
└── Warehouse Service
Без distributed tracing невозможно:
- Понять, какой сервис в цепочке вызвал задержку
- Отследить, где произошла ошибка
- Увидеть зависимости между сервисами
- Оценить влияние одного сервиса на остальные
Основные концепции
| Концепция | Описание |
|---|---|
| Trace | Полная запись обработки одного запроса через все сервисы (уникальный traceId) |
| Span | Единица работы внутри trace: spanId, parentSpanId, operationName, startTime, duration, tags, status |
| Context Propagation | Механизм передачи traceId/spanId между сервисами через HTTP-заголовки, Kafka headers, gRPC metadata |
W3C Trace Context (стандарт)
Пример
GET /api/orders HTTP/1.1
Host: order-service
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
# traceparent формат:
# {version}-{trace-id}-{parent-id}-{trace-flags}
# 00 - 4bf92f... - 00f067... - 01 (sampled)
Waterfall-диаграмма (визуализация трейса)
Пример
TraceID: abc123def456
├── API Gateway: GET /api/orders [250ms] ────────────────────────────────────
│ ├── Order Service: getOrders [200ms] ────────────────────────────────
│ │ ├── PostgreSQL: SELECT * FROM orders [15ms] ──────
│ │ ├── Redis: GET cache:orders [2ms] ──
│ │ ├── Inventory Service: checkStock [120ms] ─────────────────
│ │ │ └── Warehouse DB: SELECT stock [10ms] ────
│ │ └── Payment Service: validatePayments [50ms] ──────────
│ │ └── Stripe API: GET /charges [40ms] ────────
│ └── Auth: validateToken [5ms] ──
По этой диаграмме видно:
- Общее время запроса — 250ms
- Самая долгая операция — checkStock (120ms) — кандидат на оптимизацию
- Запросы к Redis и Auth выполняются быстро
- Order Service ждёт последовательно Inventory и Payment — можно параллелить
Стратегии семплирования (Sampling)
Трейсить 100% запросов в production дорого. Стратегии:
| Стратегия | Описание | Когда использовать |
|---|---|---|
| Head-based | Решение о семплировании принимается в начале трейса | Простая, но может пропустить интересные трейсы |
| Tail-based | Решение принимается после завершения трейса | Позволяет сохранять трейсы с ошибками или высокой задержкой |
| Rate limiting | Фиксированное количество трейсов в секунду | Контроль нагрузки |
| Probabilistic | Фиксированный процент (1%, 10%) | Простейший вариант |
Пример tail-based sampling в OTel Collector
processors:
tail_sampling:
decision_wait: 10s
policies:
- name: errors
type: status_code
status_code: {status_codes: [ERROR]}
- name: slow-traces
type: latency
latency: {threshold_ms: 1000}
- name: probabilistic
type: probabilistic
probabilistic: {sampling_percentage: 10}
Важное
- Context propagation — критически важен. Если хотя бы один сервис в цепочке не передаёт контекст, трейс обрывается.
- Span — не лог. Span описывает единицу работы с началом и концом. Не создавайте span для каждой строки кода.
- Instrumentation библиотеки (JDBC, HTTP-клиенты, Kafka, gRPC) автоматически создают spans — не нужно оборачивать каждый вызов вручную.
- Sampling обязателен в production: без него overhead на трейсинг может составлять 5-15% ресурсов.
Частые ошибки
- Потеря контекста при асинхронных вызовах: при использовании
@Async,CompletableFuture, реактивных цепочек контекст нужно передавать явно. - Слишком детальные спаны: создание span на каждый вызов метода перегружает систему. Спаны нужны для I/O-операций и бизнес-логики.
- Игнорирование семплирования: 100% трейсов в production — это огромный объём данных и нагрузка на хранилище.
- Несогласованные имена операций:
getOrder,GET_ORDER,order.get— разные имена для одной операции усложняют анализ.
Как используется в 2026
- W3C Trace Context — стандарт де-факто для propagation.
- OpenTelemetry — единый API и SDK для трейсинга, заменивший Jaeger client, Zipkin Brave и OpenTracing.
- Grafana Tempo и Jaeger v2 — популярные бэкенды для хранения трейсов.
- Trace-based testing (Tracetest) — использование трейсов для написания интеграционных тестов.
- Continuous profiling + tracing — связка профилирования с трейсами (Grafana Pyroscope).
На собеседовании: объясните концепции Trace/Span/Context Propagation и покажите, что умеете читать waterfall-диаграмму. Упомяните необходимость семплирования в production и W3C Trace Context как стандарт. Частая ошибка — забыть про потерю контекста в асинхронных вызовах.