Очереди — самое сложное место трассировки: «запрос» и «обработка» разделены во времени и пространстве. Разбираем конвенции для messaging и две модели трассировки потребителей.
Конвенция: producer span / consumer span
Семантические конвенции OTel определяют для messaging три вида спанов:
- producer — публикация сообщения
(
messaging.operation.type=publish); - process — обработка на потребителе
(
messaging.operation.type=process); - Сама передача — не спан, а «передача контекста» через свойства сообщения.
Контекст кладётся в заголовки/свойства сообщения (Kafka headers, RabbitMQ headers, SNS/SQS message attributes). Инструментированные клиенты (kafka-python, amqplib, spring-kafka, confluent-kafka) делают это автоматически.
Две модели чтения у потребителя
| Модель | Как выглядит | Когда |
|---|---|---|
| Продолжение трейса | спан process — ребёнок спана producer: один длинный трейс через очередь | сообщения обрабатываются быстро и 1:1 |
| Новый трейс с линком | консюмер открывает свой трейс, parent — not set, связь через span link на producer-контекст | задержки обработки, ретраи, партиционная конвейерность |
OTel по умолчанию делает продолжение трейса. Это наглядно, но помните: трейс «живёт» от запроса до конца обработки сообщения, даже если это часы. Для высоколатентных конвейеров предпочитайте отдельные трейсы + ссылки.
Батчи: много сообщений за один poll
Kafka-консюмер читает пачку записей за раз. Варианты:
- Один спан
processна батч (атрибутmessaging.batch.message_count) — дёшево, но теряется связь «сообщение → результат»; - Спан на каждое сообщение (конвейерно) — связь полная, спанов больше;
- Гибрид: спан на батч + события/линки на проблемные сообщения. Рекомендация по умолчанию при больших батчах;
- Отдельно трассируйте ретраи и DLQ: публикация в DLQ — producer-спан со ссылкой на исходное сообщение.
БД-батчи и массовые операции
Тот же принцип для «одной операции с N сущностями»: спан «bulk insert 1000 rows» вместо 1000 спанов; детали — события или атрибут-счётчик. Иначе объём спанов растёт линейно с батчем, а UI превращается в лапшу.
💡 Правило резюме: спан — на единицу работы, значимую для диагноза. Батч из 1000 элементов — одна единица, пока все не сломались; проблемный элемент — отдельный спан/событие только когда стал исключением.
Практика
- Свяжите через трейс «продюсер → Kafka → консюмер» на инструментированных клиентах; найдите в UI цепочку publish → process в одном трейсе.
- Внедрите задержку обработки 30с и наблюдайте «длинный» трейс; решите, когда вам захочется модель «новый трейс + линк» — и реализуйте её.
- Сделайте батч-консюмер 50 сообщений: сравните два варианта трассировки по объёму спанов и читаемости.
- Трассируйте DLQ-путь: неудачное сообщение → спан публикации в DLQ со ссылкой на исходный producer-спан.
Мини-квиз
1. Где «живёт» контекст между продюсером и консюмером? — В свойствах/заголовках сообщения.
2. Когда не стоит продолжать один трейс через очередь? — Когда обработка сильно отложена или независима: лучше новый трейс с span-линком.
3. Как трассировать батч из 1000 сообщений? — Спан на батч + счётчик; детали — событиями по проблемам.