ASP.NET Core 는 Jaeger 를 이용 하여 분포 식 추적 상세 해 를 실현 합 니 다.

12963 단어 corejaeger분포 식
머리말
최근 우리 회사 의 일부.NET Core 프로젝트 가 Jaeger 에 접 속 했 으 니.NET 팀 의 기술 스 택 을 조금 보완 한 셈 이다.
왜 스 카 이 워 크 가 아 닌 제 이 거 를 선 택 했 는 지 에 대해 서 는 대답 할 수 밖 에 없 었 다.
얼마 전에 도 CSharp Corner 에서 비슷 한 소 개 를 한 적 이 있 습 니 다.
Exploring Distributed Tracing Using ASP.NET Core And Jaeger
이제 본론 으로 돌아 가서 Jaeger 의 프로필 을 살 펴 보 겠 습 니 다.
Jaeger 의 간단 한 소개

Jaeger 는 Uber 가 소스 를 시작 하 는 분포 식 추적 도구 로 주로 마이크로 서 비 스 를 기반 으로 하 는 분포 식 시스템 에 모니터링 과 고장 진단 을 제공한다.아래 내용 을 담 았 습 니 다.
  • Distributed context propagation
  • Distributed transaction monitoring
  • Root cause analysis
  • Service dependency analysis
  • Performance / latency optimization
  • 다음은 간단 한 예 를 통 해 체험 해 보 자.
    예시
    이 예제 에서 우 리 는 jaegertracing/all-in-one 이라는 docker 의 미 러 로 만 들 었 습 니 다.현지의 개발 테스트 환경 이기 때문에 추가 저장 소 를 만 들 필요 가 없습니다.이 느낌 은 비교적 마음 에 듭 니 다.
    우 리 는 두 개의 주요 nuget 가방 을 사용 할 것 이다.
    제 이 거 는 공식 클 라 이언 트 입 니 다
  • OpenTracing.contrib.NetCore.Unofficial 이것 은.NET Core 프로 브 에 대한 처리 입 니 다.opentracing-contrib/csharp-netcore 라 는 프로젝트 에서 이 식 된 것 입 니 다.
    그리고 저 희 는 두 개의 API 프로젝트 를 만 들 것 입 니 다.하 나 는 AService 이 고 하 나 는 BService 입 니 다.
    이 가운데 BService 는 캐 시 에서 데 이 터 를 읽 고 읽 지 못 하면 EF Core 를 통 해 sqlite 에서 읽 은 다음 캐 시 에 기록 하고 결 과 를 되 돌려 주 는 인 터 페 이 스 를 제공 합 니 다.
    AService 는 HttpClient 를 통 해 BService 의 인 터 페 이 스 를 호출 하여 호출 체인 을 형성 합 니 다.
    시작 하기 전에 docker-compose.yml 을 설정 합 니 다.
    
    version: '3.4'
    
    services:
     aservice:
     image: ${DOCKER_REGISTRY-}aservice
     build:
     context: .
     dockerfile: AService/Dockerfile
     ports:
     - "9898:80" 
     depends_on:
     - jagerservice
     - bservice
     networks: 
     backend:
     
     bservice:
     image: ${DOCKER_REGISTRY-}bservice
     build:
     context: .
     dockerfile: BService/Dockerfile
     ports:
     - "9899:80"
     depends_on:
     - jagerservice 
     networks: 
     backend:
     
     jagerservice:
     image: jaegertracing/all-in-one:latest
     environment:
     - COLLECTOR_ZIPKIN_HTTP_PORT=9411 
     ports:
     - "5775:5775/udp"
     - "6831:6831/udp"
     - "6832:6832/udp"
     - "5778:5778"
     - "16686:16686"
     - "14268:14268"
     - "9411:9411"
     networks: 
     backend:
     
    networks: 
     backend: 
     driver: bridge
    그리고 두 프로젝트 의 Startup 에 아래 설정 을 추가 합 니 다.주로 Jaeger 와 관련 된 것 입 니 다.
    
    public void ConfigureServices(IServiceCollection services)
    {
     // others ....
     
     // Adds opentracing
     services.AddOpenTracing();
    
     // Adds the Jaeger Tracer.
     services.AddSingleton<ITracer>(serviceProvider =>
     {
     string serviceName = serviceProvider.GetRequiredService<IHostingEnvironment>().ApplicationName;
     
     var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
     var sampler = new ConstSampler(sample: true);
     var reporter = new RemoteReporter.Builder()
      .WithLoggerFactory(loggerFactory)
      .WithSender(new UdpSender("jagerservice", 6831, 0))
      .Build();
    
     var tracer = new Tracer.Builder(serviceName)
      .WithLoggerFactory(loggerFactory)
      .WithSampler(sampler)
      .WithReporter(reporter)
      .Build();
    
     GlobalTracer.Register(tracer);
    
     return tracer;
     });
    }
    여기 서 주의해 야 할 것 은 우리 가 상황 에 따라 sampler 를 선택해 야 한 다 는 것 이다.여기 서 가장 간단 한 ConstSampler 를 사용 했다 는 것 을 보 여 주 는 것 이다.
    BService 프로젝트 로 돌아 가 SQLite 와 Easy Caching 에 대한 지원 을 추가 합 니 다.
    
    public void ConfigureServices(IServiceCollection services)
    {
     // Adds an InMemory-Sqlite DB to show EFCore traces.
     services
     .AddEntityFrameworkSqlite()
     .AddDbContext<BDbContext>(options =>
     {
      var connectionStringBuilder = new SqliteConnectionStringBuilder
      {
      DataSource = ":memory:",
      Mode = SqliteOpenMode.Memory,
      Cache = SqliteCacheMode.Shared
      };
      var connection = new SqliteConnection(connectionStringBuilder.ConnectionString);
    
      connection.Open();
      connection.EnableExtensions(true);
    
      options.UseSqlite(connection);
     });
    
     // Add EasyCaching Inmemory provider.
     services.AddEasyCaching(options =>
     {
     options.UseInMemory("m1");
     });
    }
    그리고 컨트롤 러 위 가 쉬 워 요.
    
    // GET api/values
    [HttpGet]
    public async Task<IActionResult> GetAsync()
    {
     var provider = _providerFactory.GetCachingProvider("m1");
    
     var obj = await provider.GetAsync("mykey", async () => await _dbContext.DemoObjs.ToListAsync(), TimeSpan.FromSeconds(30));
    
     return Ok(obj);
    }
    AService 는 HttpClient 를 통 해 위의 이 인 터 페 이 스 를 호출 하면 됩 니 다.
    
    // GET api/values
    [HttpGet]
    public async Task<string> GetAsync()
    {
     var res = await GetDemoAsync();
     return res;
    }
     
    private async Task<string> GetDemoAsync()
    {
     var client = _clientFactory.CreateClient();
    
     var request = new HttpRequestMessage
     {
     Method = HttpMethod.Get,
     RequestUri = new Uri($"http://bservice/api/values")
     };
    
     var response = await client.SendAsync(request);
    
     response.EnsureSuccessStatusCode();
    
     var body = await response.Content.ReadAsStringAsync();
    
     return body;
    }
    여기까지 오 면 코드 는 ok 입 니 다.다음은 효 과 를 보 겠 습 니 다.
    먼저 통과 하 다http://localhost:9898/api/values/AService 몇 번 방문 하기
    아마 이런 결 과 를 얻 을 수 있 을 거 예요.

    그리고 Jaeger 의 인터페이스 에 가면 두 서비스 가 이미 등록 되 었 음 을 볼 수 있 습 니 다.

    A,B 중 하 나 를 선택 하여 검색 하면 아래 의 결 과 를 볼 수 있 습 니 다.

    이것 은 바로 가장 바깥쪽 으로 거시적인 정 보 를 요청 하 는 것 을 볼 수 있다.
    우 리 는 인터페이스의 마지막,즉 첫 번 째 요청 을 선택 하고 들 어가 서 세부 사항 을 살 펴 보 자.

    위의 그림 에서 대충 알 수 있 듯 이 어떤 조작 을 했 는 지 AService 에 요청 하면 HTTP 요청 이 BService 에 시 작 됩 니 다.BService 는 Easy Caching 을 통 해 캐 시 를 찾 습 니 다.캐 시 에 데이터 가 없 는 것 이 분명 하고 데이터 베 이 스 를 읽 습 니 다.
    다른 요청 과 비교 해 보면 데이터 베 이 스 를 찾 는 작업 이 적 다 는 것 을 알 수 있다.위 에는 10 개의 span 이 있 고 아래 는 8 개 밖 에 없 는 이유 다.

    두 요청 의 대비 도 를 살 펴 보 자.

    위의 그림 에서 빨간색 과 녹색 덩어리 는 두 가지 요구 의 차이 점 이다.
    다른 디 테 일 을 살 펴 보면 아래 와 같은 내용 을 발견 할 수 있다.

    로그 와 관련 된 것 이 많 습 니 다.이 물건 들 은 실제 적 인 역할 이 많 지 않 을 수도 있 습 니 다.로그 의 단 계 를 조정 하여 Jaeger 에 쓰 지 못 하 게 할 수 있 습 니 다.
    아니면 아래 방법 으로 걸 러 내 거나.
    
    services.AddOpenTracing(new System.Collections.Generic.Dictionary<string,LogLevel>
    {
     {"AService", LogLevel.Information}
    });
    마지막 으로 의존 도 야.

    마지막 에 쓰다
    비록 Jaeger 는 사용 하기 가 매우 간단 하지만 약간 옥 에 티 가 있 습 니 다.그러나 이 냄비 는 Jaeger 가 외 워 서 는 안 됩 니 다.주로 우리 가 자주 사용 하 는 라 이브 러 리 가 Diagnostic 을 직접적 으로 지원 하지 않 아서 감시 할 수 있 는 것 이 약간 적 습 니 다.
    그러나 github 에서 발견 되 었 습 니 다ClrProfiler.Trace이 프로젝트 는 clrprofiler 를 통 해 위의 문 제 를 해결 할 수 있 습 니 다.
    마지막 으로 본문의 예시 코드 이다
    JaegerDemo
    총결산
    이상 은 이 글 의 모든 내용 입 니 다.본 고의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가 치 를 가지 기 를 바 랍 니 다.여러분 의 저희 에 대한 지지 에 감 사 드 립 니 다.
  • 좋은 웹페이지 즐겨찾기