문제
.NET 에이전트가 처리량이 높은 .NET Framework 애플리케이션에 연결된 경우 몇몇 고객이 높은 스레드 경합을 관찰했다고 보고했습니다. 프로세스 덤프 및 스택 추적을 검토하면 AppDomain.GetData()
호출로 인해 많은 스레드가 차단될 수 있습니다.
가능한 해결책
.NET 에이전트 버전 9.7에서는 .NET 에이전트 에서 AppDomain
저장소를 사용하지 않도록 설정하는 새로운 환경 변수가 도입되었습니다.
NEW_RELIC_DISABLE_APPDOMAIN_CACHING=true
주의
이 환경 변수는 AppDomain.GetData()
에 대한 에이전트 호출에서 잠금 경합을 제거하지만 이 환경 변수가 활성화되면 .NET 에이전트의 총 오버헤드가 증가합니다. 테스트에서 이로 인해 잠금은 줄어들었지만 테스트 응용 프로그램에 연결된 .NET 에이전트의 최대 응용 프로그램 처리량은 낮아졌습니다.
우리는 이 새로운 구성 옵션을 시도한 이 문제를 겪고 있는 고객의 모든 피드백에 매우 관심이 있습니다. 이 구성 옵션을 시도하는 경우 경험을 설명하는 .NET용 GitHub 리포지토리에 문제를 생성하십시오.
원인
.NET 에이전트는 메서드를 계측하기 위해 메서드 서명 정보에 액세스해야 합니다. 기본적으로 .NET Framework 애플리케이션의 경우 에이전트는 리플렉션을 통해 이 메서드 정보를 로드하고 나중에 사용할 수 있도록 AppDomain
에 캐시합니다. 이것은 일반적인 최적화를 위한 것이지만 몇몇 고객은 이 동작을 둘러싼 높은 스레드 잠금 경합을 경험했으며 이것이 서비스가 느려지거나 응답하지 않는 근본 원인이라고 생각합니다.
Microsoft 소스 코드를 검사한 후 AppDomain.GetData()
를 호출하면 실제로 전역 잠금이 발생합니다.
.NET 에이전트는 .NET Core 애플리케이션에 대해 메서드 정보 캐싱 체계를 전혀 사용하지 않고 유사한 스레드 잠금 경합 문제를 보고한 고객이 없기 때문에 에이전트가 .NET에서 동일한 방식으로 작동하도록 환경 변수를 노출하기로 결정했습니다. 프레임워크 애플리케이션.