.NET 분산 추적 개념
분산 추적은 엔지니어가 애플리케이션 내의 오류 및 성능 문제, 특히 여러 컴퓨터 또는 프로세스에 분산될 수 있는 문제를 지역화하는 데 도움이 되는 진단 기술입니다. 분산 추적이 유용한 위치에 대한 일반적인 정보는 분산 추적 개요 참조하세요.
추적 및 활동
애플리케이션이 새 요청을 받을 때마다 해당 요청은 트레이스와 연결될 수 있습니다. .NET으로 작성된 애플리케이션 구성 요소에서 추적의 작업 단위는 System.Diagnostics.Activity 인스턴스로 표현되고 추적은 전체적으로 이러한 활동의 트리를 형성하며, 잠재적으로 여러 고유 프로세스에 걸쳐 있습니다. 새 요청에 대해 생성된 첫 번째 작업은 추적 트리의 루트를 형성하며 요청을 처리하는 전체 기간 및 성공/실패를 추적합니다. 필요에 따라 자식 활동을 만들어 개별적으로 추적할 수 있는 여러 단계로 작업을 세분화할 수 있습니다. 예를 들어 웹 서버에서 특정 인바운드 HTTP 요청을 추적하는 활동이 있는 경우 요청을 완료하는 데 필요한 각 데이터베이스 쿼리를 추적하기 위해 자식 활동을 만들 수 있습니다. 이렇게 하면 각 쿼리의 기간과 성공을 독립적으로 기록할 수 있습니다. 활동은 각 작업 단위에 대해 OperationName, Tags이라는 이름-값 쌍 및 Events와 같은 다양한 정보를 기록할 수 있습니다. 이름은 수행 중인 작업의 유형을 식별하고, 태그는 작업의 설명 매개 변수를 기록할 수 있으며, 이벤트는 타임스탬프가 지정된 진단 메시지를 기록하는 간단한 로깅 메커니즘입니다.
메모
분산 추적의 작업 단위에 대한 또 다른 일반적인 업계 이름은 'Spans'입니다. .NET은 이 개념에 대해 'Span'이라는 이름이 잘 확립되기 전에 수년 전에 '활동'이라는 용어를 채택했습니다.
활동 ID
분산 추적 트리의 활동 간의 Parent-Child 관계는 고유한 ID를 사용하여 설정됩니다. . NET의 분산 추적 구현은 .NET 5 이상의 기본값인 W3C 표준 TraceContext및 이전 버전과의 호환성을 위해 사용할 수 있는 '계층적'이라는 이전 .NET 규칙이라는 두 가지 ID 체계를 지원합니다. 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통해 액세스할 수 있는 해당 스레드에서 발생하는 작업을 추적하는 해당 활동 개체가 있을 수 있습니다. 현재 작업은 스레드의 모든 동기 호출을 따라 자동으로 흐르고 다른 스레드에서 처리되는 비동기 호출을 따릅니다. 활동 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 개체를 교환하고 사용자 지정된 정보 전달 규칙을 설정할 수 있습니다.
견본 추출
높은 처리량 애플리케이션에서 성능을 향상시키기 위해 .NET의 분산 추적은 모든 추적을 기록하는 대신 추적의 하위 집합만 샘플링할 수 있도록 지원합니다. 권장 ActivitySource.StartActivity API로 생성된 활동에 대해, 원격 분석 라이브러리는 ActivityListener.Sample 콜백을 사용하여 샘플링을 제어할 수 있습니다. 로깅 라이브러리는 활동을 전혀 만들지 않도록 선택하거나, 배포 추적 ID를 전파하는 데 필요한 최소한의 정보로 만들거나, 전체 진단 정보로 채울 수 있습니다. 성능 오버헤드를 증가시키면서 진단 기능을 강화하는 선택의 균형을 조정하는 것입니다. Activity.Activity 및 DiagnosticSource.StartActivity 호출하는 이전 패턴을 사용하여 시작된 활동은 먼저 DiagnosticSource.IsEnabled호출하여 DiagnosticListener 샘플링을 지원할 수도 있습니다. 전체 진단 정보를 캡처하는 경우에도 .NET 구현은 효율적인 수집기와 결합되어 최신 하드웨어에서 약 마이크로초 안에 활동을 만들고, 채우고, 전송할 수 있도록 설계되었습니다. 샘플링은 기록되지 않은 각 활동에 대한 계측 비용을 100나노초 미만으로 줄일 수 있습니다.
다음 단계
.NET 애플리케이션에서 분산 추적 사용을 시작하는 예제 코드는 분산 추적 계측참조하세요.
.NET에서 기본적으로 내보낸 활동 목록은 .NET의 기본 제공 활동을 참조하세요.
.NET