데이터 라인으로 분산 추적 마이크로 서비스

이 글은 ZOZO #4 Advent Calendar 2021 17일째 되는 글이다.
이번에는 마이크로 서비스의 데이터독의 분산 추적에 도전했기 때문에 그것을 기록하고 싶습니다.
구성은 다음과 같다.

처리 프로세스는 다음과 같습니다.
  • Classic ASP에서 Java API [A]의 등록 API 호출
  • Java API 【A】 DynamoDB에 처리 시작 기록을 등록
  • Java API 【A】 로그인 정보를 Kinesis Data Streams(이하 KDS라고 함)
  • 에 전달
  • Java API【B】KDS에서 정보를 추출하여 처리
  • Java API 【B】 레코드를 처리 완료 DynamoDB
  • 로 업데이트
    이를 바탕으로 데이터를 추가하여 일련의 처리를 추적한다.
    먼저 Java API [A]의 등록 API를 사용하여 Trace를 만듭니다.
    public record Trace(TraceId traceId, DdCarrier ddCarrier) {
      public static Trace convert(String traceId) {
        Tracer tracer = GlobalTracer.get();
        Map<String, String> ddMap = new HashMap<>();
        tracer.inject(
            tracer.activeSpan().context(),
            Format.Builtin.TEXT_MAP_INJECT,
            new TextMapInjectAdapter(ddMap));
        return new Trace(new TraceId(traceId), new DdCarrier(ddMap));
      }
    }
    
    제작된 Trace를 KDS에 전달하고 Java API [A]의 로그인 API 반환값으로 다음 내용을 반환합니다.
  • x-datadog-trace-id
  • x-datadog-sampling-priority
  • x-datadog-parent-id
  • Java API [B]는 KDS를 통해 데이터 dog의 매개 변수를 수신합니다.
    받은 매개 변수에 따라 Span을 생성하고 등록된 API의 trace와 연결합니다.
    또한 Java API [A]의 참조 API도 Classic ASP를 통해 동일하게 처리됩니다.
    Tracer tracer = GlobalTracer.get();
    SpanBuilder spanBuilder =
        new SpanBuilder()
            .generate(
                tracer,
                "処理API",
                traceId,
                datadogTraceId,
                datadogParentId,
                datadogSamplingPriority);
    Span span = spanBuilder.start();
    try (Scope scope = tracer.scopeManager().activate(span)) {
      // 処理
    } catch (Exception e) {
      span.setTag(DDTags.ERROR_MSG, e.getMessage());
      span.setTag(DDTags.ERROR_STACK, Arrays.toString(e.getStackTrace()));
      throw e;
    } finally {
      span.finish();
    }
    
    public class SpanBuilder {
      public Tracer.SpanBuilder generate(
          Tracer tracer,
          String operationName,
          String traceId,
          String datadogTraceId,
          String datadogParentId,
          String datadogSamplingPriority) {
        Tracer.SpanBuilder spanBuilder =
            tracer
                .buildSpan(operationName)
                .withTag("trace-id", traceId)
                .withTag("datadog-trace-id", datadogTraceId)
                .withTag("datadog-sampling-priority", datadogSamplingPriority)
                .withTag("datadog-parent-id", datadogParentId);
        Map<String, String> ddCarrier = new HashMap<>();
        ddCarrier.put("x-datadog-trace-id", datadogTraceId);
        ddCarrier.put("x-datadog-sampling-priority", datadogSamplingPriority);
        ddCarrier.put("x-datadog-parent-id", datadogParentId);
        SpanContext spanContext =
            tracer.extract(Format.Builtin.TEXT_MAP_EXTRACT, new TextMapExtractAdapter(ddCarrier));
        return spanBuilder.asChildOf(spanContext);
      }
    }
    
    이렇게 하면 다음과 같이 일맥상통하여 추적 처리할 수 있다.
    처리 절차가 추적하기 쉬워지고 오류 등이 발생할 때도 원인을 확인하기 쉽다.

    내일은 @EnKUMA의 보도입니다.
    읽어주셔서 감사합니다.
    참조: 데이터dog 방차 추적 상하문 삽입 및 추출

    좋은 웹페이지 즐겨찾기