Требования: В архитектуре микросервисов при возникновении проблем часто очень сложно устранить неполадку, не зная, является ли это исключением, выпущенным сервисом, может быть, сервис записывает ошибку или возникает проблема с информацией, передаваемой сервисом, вызывающим сервис. Если контекст всех запросов можно записать, то есть ссылку на весь запрос транзакции, критически важно устранить и проанализировать проблему.
Обзор:
Трассировки стека исключений идеально подходят для приложений, ориентированных на один процесс, например, для монолитной системы применения. Но с другой стороны, для работы с распределёнными приложениями, такими как архитектуры микросервисов, трассировки стека недостаточны для отображения общей трассы сообщения. Именно поэтому необходимы инструменты и стандарты распределённого трассировки. W3C определяет стандарт для такого типа трассировки, называемый Trace Context.
Стандарт Trace Context
Документация контекста трассы W3C:Вход по гиперссылке виден.
Спецификация W3C Trace Context определяет стандарты и форматы для HTTP-заголовков для передачи распределённой информации о контексте трассировки. Он определяет 2 поля, которые используются для распространения потока следов в заголовке HTTP-запроса. Давайте рассмотрим эти два поля в стандартном определении:
- traceparent: 用来描述在追踪图谱中到达请求的位置。它表示在追踪系统中到达请求的通用格式,被所有的 vendor 所理解。
- tracestate: 使用 vendor 特定的数据表示形式来扩展 traceparent,使用 name/value 对形式。在 tracestate 中保存信息是可选的。
Traceparent Field
Спецификация поля traceparent определяется в виде расширенной парадигмы Баккоса (ABNF) и состоит из 4 частей:
версия - traceid - parentid/spanid - traceflags Например:
00-480e22a2781fe54d992d878662248d94-b4b37b64bb3f6141-00
- version: 8 位,系统适配的追踪上下文版本,当前位 00
- trace-id: 16 字节,追踪整体的标识。用于在系统中标识一个分布式追踪整体,Значение в той же ссылке абсолютно одинаковое。
- parent-id/span-id: 8 байт для выражения родителя текущего охвата в входящем или исходящем запросе.
- trace-flags: 8 位,调用者的建议标志,可以考虑为调用者的建议,限制为 3 个原因:信息或是滥用,调用方的错误,或者在调用方与被调用方的不同负载。
Все поля кодируются в шестнадцатеричном формате, как показано на изображении ниже:
Распределённое трассирование .NET
Распределённое трассирование — это диагностический метод, который помогает инженерам локализовать сбои и проблемы с производительностью в приложениях, особенно если они распределены между несколькими компьютерами или процессами. Эта техника связывает работу, выполняемую разными компонентами приложения, через отслеживание запросов в приложении, и отделяет её от других задач, которые приложение может выполнять при обработке параллельных запросов. Например, балансировщик нагрузки может сначала получить запрос на типичный веб-сервис, затем переслать его на процесс веб-сервера и отправить несколько запросов к базе данных. С помощью распределённой трассировки инженеры могут определить, не прошли ли эти шаги, сколько времени занимает каждый шаг и какие сообщения могут быть записаны при выполнении каждого шага.
В .NET библиотека System.Diagnostics.Activity настроена на использование стандарта W3C. Заголовок traceparent в стиле W3C Request-ID был добавлен в ASP.NET Core 2.0. Чтобы изменить заголовок traceparent, соответствующий контексту W3C, при запуске программы установите статическое свойство Activity.DefaultIdFormat на W3C. Код таков:
Процесс тестирования,Браузер -> A сервис (/http, бэкэнд использует HttpClient для запроса B сервиса) интерфейс -> B сервис (/test), Сервис A выводит свой собственный Trace Context и Trace Context сервиса B, код выглядит следующим образом:
Старт сервисов A и B, как показано на следующем рисунке:
Браузер открывает сервис A, как показано на следующем рисунке:
Id: 00-9891603e6c4921598951f425d98e4df7-bd06e8d507a43f42-00
TraceId: 9891603e6c4921598951f425d98e4df7
SpanId: bd06e8d507a43f42
ParentId:
Содержимое ответа: {"id":"00-9891603e6c4921598951f425d98e4df7-8874f9b2f9c0702e-00","traceId":"9891603e6c4921598951f425d98e4df7","spanId":"8874f9b2f9c0702e","parentId": "00-9891603e6c4921598951f425d98e4df7-e0336cc56a4f2150-00","traceFlags":"None","isSampled":false}
--------------------------------------------------
Name: HttpHandlerDiagnosticListener
DateTime: 2025/12/22 9:37:22
Id: 00-9891603e6c4921598951f425d98e4df7-e0336cc56a4f2150-00
TraceId: 9891603e6c4921598951f425d98e4df7
SpanId: e0336cc56a4f2150
ParentId: 00-9891603e6c4921598951f425d98e4df7-bd06e8d507a43f42-00
Key: System.Net.Http.HttpRequestOut.Stop, Value: { Response = StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
{ Дата: Пн, 22 дек 2025 01:37:21 GMT Официант: Kestrel Кодировка передачи: фрагментированная Связь: поддерживать живых Тип содержания: приложение/json; Чарсет=UTF-8 }, Request = Метод: GET, RequestUri: 'http://localhost.charlesproxy.com:5551/test', Версия: 1.1, Content: <null>, Заголовки:
{ Traceparent: 00-9891603E6C4921598951F425D98E4df7-E0336cc56A4F2150-00 }, RequestTaskStatus = RanToCompletion } -------------------------------------------------- С помощью инструмента захвата пакетов Charles Proxy запрос и ответ следующие:
Если вы хотите отключить HttpClient от передачи traceparent, переменные среды устанавливаются следующим образом:
Ссылка:
Вход по гиперссылке виден.
Вход по гиперссылке виден.
Вход по гиперссылке виден.
Вход по гиперссылке виден.
Вход по гиперссылке виден.
Вход по гиперссылке виден. |