[C#] 분산 추적 이란?

참고


.NET 분산 추적 개념

  • 분산 추적은 엔지니어가 특히 여러 머신 또는 프로세스에 분산될 수 있는 애플리케이션 내에서 오류 및 성능 문제를 지역화 하는 데 오움이 되는 진단 기술입니다.

추적 및 활동

애플리케이션이 새 요청을 수신할 때마다 해당 요청을 추적과 연결할 수 있습니다. .NET으로 작성된 애플리케이션 구성 요소에서 추적의 작업 단위는 System.Diagnostics.Activity의 인스턴스로 나타내며 전체적으로 추적은 해당 활동의 트리를 구성하고 많은 개별 프로세스에 걸쳐 있을 수 있습니다. 새 요청에 대해 만들어진 첫 번째 활동은 추적 트리의 루트를 구성하며 요청을 처리하여 전체 시간 및 성공/실패를 추적합니다. 필요한 경우 자식 활동을 만들어 개별적으로 추적할 수 있는 여러 단계로 작업을 세분화할 수 있습니다. 예를 들어 웹 서버에서 특정 인바운드 HTTP 요청을 추적한 활동이 제공된 경우 요청을 완료하는 데 필요한 각 데이터베이스 쿼리를 추적하기 위해 자식 활동을 만들 수 있습니다. 이렇게 하면 각 쿼리의 기간 및 성공을 개별적으로 기록할 수 있습니다. 활동은 OperationName, 이름 값 쌍 Tags, Events와 같은 각 작업 단위의 기타 정보를 기록할 수 있습니다. 이름은 수행되는 작업의 유형을 식별하며 태그는 작업의 설명 매개 변수를 기록할 수 있고 이벤트는 타임스탬프 진단 메시지를 기록하는 간단한 로깅 메커니즘입니다.

분산 추적에서 작업 단위의 또 다른 일반적인 업계 이름은 ‘Span’입니다. .NET은 이 개념에 대해 ‘범위’라는 이름이 제대로 확립되기 여러 해 전에 ‘활동’이라는 용어를 채택했습니다.


작업 ID

분산 추적 트리에서 활동 간 부모-자식 관계는 고유한 ID를 사용하여 설정됩니다. .NET의 분산 추적 구현은 다음과 같은 두 가지 ID 체계를 지원합니다. W3C 표준 TraceContext는 .NET 5 이상의 기본값이며, ‘계층 구조’라는 이전 .NET 규칙은 이전 버전과의 호환성을 위해 사용할 수 있습니다. Activity.DefaultIdFormat은 사용되는 ID 체계를 제어합니다. W3C TraceContext 표준에서 모든 추적에는 전역적으로 고유한 16바이트 추적 ID(Activity.TraceId)가 할당되고 추적 내 모든 활동에는 고유한 8바이트 범위 ID(Activity.SpanId)가 할당됩니다. 각 활동은 추적 ID, 자체 범위 ID, 부모의 범위 ID(Activity.ParentSpanId)를 기록합니다. 분산 추적은 프로세스 경계에 걸쳐 작업을 추적할 수 있으므로 부모 및 자식 활동이 같은 프로세스에 없을 수도 있습니다. 추적 ID 및 부모 범위 ID를 조합하면 부모 활동이 있는 프로세스와 관계없이 전역적으로 부모 활동을 고유하게 식별할 수 있습니다.

Activity.DefaultIdFormat은 새 추적을 시작하는 데 사용되는 ID 형식을 제어하지만, 기본적으로 기존 추적에 새 활동을 추가하면 부모 활동이 사용 중인 형식이 사용됩니다. Activity.ForceDefaultIdFormat을 true로 설정하면 이 동작이 재정의되고 부모가 다른 ID 형식을 사용하는 경우에도 모든 새 활동이 DefaultIdFormat을 사용하여 생성됩니다.


활동 시작 및 중지

프로세스의 각 스레드에는 Activity.Current를 통해 액세스할 수 있는, 해당 스레드에서 발생하는 작업을 추적 중인 해당 Activity 개체가 있을 수 있습니다. 현재 활동은 서로 다른 스레드에서 처리되는 비동기 호출뿐만 아니라 한 스레드의 모든 동기 호출을 따라 자동으로 이동합니다. 활동 A가 스레드의 현재 활동이고 코드가 새 활동 B를 시작하면 B는 해당 스레드에서 새로운 현재 활동이 됩니다. 또한 기본적으로 활동 B는 활동 A를 부모로 처리합니다. 활동 B가 나중에 중지되면 활동 A가 스레드의 현재 활동으로 복원됩니다. 활동이 시작되면 현재 시간을 Activity.StartTimeUtc로 캡처합니다. 활동이 중지되면 Activity.Duration은 현재 시간과 시작 시간의 차이로 계산됩니다.


프로세스 경계에 걸쳐 조정

프로세스 경계에 걸쳐 작업을 추적하려면 수신 프로세스가 활동 부모 ID를 참조하는 활동을 만들 수 있도록 해당 ID를 네트워크 전체에 전송해야 합니다. W3C TraceContext ID 형식을 사용하는 경우 .NET은 표준에서 권장하는 HTTP 헤더를 사용하여 이 정보를 전송하기도 합니다. Hierarchical ID 형식을 사용하는 경우 .NET은 사용자 지정 요청 ID HTTP 헤더를 사용하여 ID를 전송합니다. 다른 많은 언어 런타임과는 달리 ASP.NET 웹 서버 및 System.Net.Http와 같은 .NET 기본 제공 라이브러리는 기본적으로 HTTP 메시지에서 활동 ID를 디코딩 및 인코딩하는 방법을 이해합니다. 이 런타임은 동기 및 비동기 호출을 통해 ID를 이동하는 방법도 이해합니다. 즉, HTTP 메시지를 받고 내보내는 .NET 애플리케이션은 앱 개발자의 특별한 코딩이나 타사 라이브러리 종속성 없이 자동으로 분산 추적 ID를 이동하는 데 참여합니다. 타사 라이브러리는 HTTP가 아닌 메시지 프로토콜을 통해 ID를 전송하기 위한 지원을 추가하거나 HTTP를 위한 사용자 지정 인코딩 규칙을 지원할 수 있습니다.


추적 수집

계측된 코드는 분산 추적의 일부로 개체를 만들 Activity 수 있지만 나중에 전체 추적을 유용하게 검토할 수 있도록 이러한 개체의 정보를 중앙 집중식 영구 저장소에서 전송하고 직렬화해야 합니다. Application Insights, OpenTelemetry 또는 타사 원격 분석이나 APM 공급업체에서 제공하는 라이브러리와 같이 이 작업을 수행할 수 있는 여러 원격 분석 컬렉션 라이브러리가 있습니다. 또는 개발자는 System.Diagnostics.ActivityListener 또는 System.Diagnostics.DiagnosticListener를 사용하여 고유한 사용자 지정 활동 원격 분석 컬렉션을 작성할 수 있습니다. ActivityListener는 개발자가 이에 대한 사전 지식이 있는지 여부에 관계없이 모든 활동 관찰을 지원합니다. 이를 통해 ActivityListener는 간단하고 유연한 범용 솔루션이 됩니다. 대조적으로, DiagnosticListener 사용은 DiagnosticSource.StartActivity를 호출하여 계측된 코드를 옵트인해야 하는 더 복잡한 시나리오이며 컬렉션 라이브러리는 시작 시 계측된 코드가 사용한 정확한 명명 정보를 알고 있어야 합니다. DiagnosticSource 및 DiagnosticListener를 사용하면 작성자와 수신기가 임의 .NET 개체를 교환하고 사용자 지정 정보 전달 규칙을 설정할 수 있습니다.

728x90

이 글을 공유하기

댓글

Designed by JB FACTORY