justgo_developer

Spring Cloud Sleuth 적용 본문

IT/Spring Cloud

Spring Cloud Sleuth 적용

다날92 2024. 3. 30. 17:07
728x90
반응형

Spring Cloud Sleuth 적용

상세

Sleuth는 RestTemplate, Feign, WebClient와 같은 스프링 진형의 HTTP Client 모듈을 사용하는 경우 Sleuth 의존성을 추가하는 것으로도 설정이 자동적으로 동작하게 됩니다

spring boot 2.X 버전에서만 Spring Cloud Sleuth 사용 가능

Spring boot 3.X 버전에서는 Micrometer Tracking으로 변경

Spring Cloud Sleuth will not work with Spring Boot 3.x onward. The last major version of Spring Boot that Sleuth will support is 2.x.

The core of this project got moved to [Micrometer Tracing](https://micrometer.io/docs/tracing) project and the instrumentations will be moved to [Micrometer](https://micrometer.io/) and all respective projects (no longer all instrumentations will be done in a single repository.

Sleuth는 RestTemplate, Feign, WebClient와 같은 스프링 진형의 HTTP Client 모듈을 사용하는 경우 Sleuth 의존성을 추가하는 것으로도 설정이 자동적으로 동작

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
dependencies {
    implementation("org.springframework.cloud:spring-cloud-starter-sleuth")
}

 

Sleuth는 B3-Propagation 타입을 기본으로 사용하여 서버간 정보를 전파

기본적으로 Sleuth는 MDC Context에 traceId와 spanId 저장

traceId : 하나의 Trace안의 모든 Span이 공유하는 값으로 최초 보낸 http 요청에 대한 ID

spanId : 각 서비스별 Id

 

X-B3-TraceId vs TraceId의 차이점

https://stackoverflow.com/questions/56767956/which-to-log-x-b3-spanid-or-spanid-x-b3-traceid-or-traceid-spring-sleuth

코틀린 코루틴에서 적용되지 않는 현상
This issue is somewhat mitigated by coroutine's slf4j support, that carries the MDC context into the coroutine:

GlobalScope.launch(MDCContext()) {
    // your code goes here
}

However, it does not work with the automatic instrumentation of RestTemplates when calling another service. The tracing headers seem not to be set on RestTemplates used within coroutines. Only solution I know of so far uses a special Callable class and is described here: https://stackoverflow.com/questions/47026664/spring-sleuth-zipkin-spans-not-nesting-in-kotlin-coroutine

→ 코틀린 + 코루틴은 작동 불가 : 실제 현재 프로젝트에 로그로는 출력 가능하나 다른 서비스에 traceId, spanId 전달 불가

일단 기본적으로 Sleuth 는MDC Context 에 traceId 와 spanId 를 저장한다.Sleuth 는 기본적으로 B3-Propagation 을 통해서 서버간 정보를 전파할 수 있다.

코루틴 적용

composite 프로젝트에 코틀린 + 코루틴으로 멀티쓰레드로 api 호출하는 로직

코루틴 내부는 MDC context가 전달되지 않음

따라서, 코루틴에 강제로 넣어줘야함.

하지만 이 방법은 실제 현재 프로젝트에 로그로는 출력 가능하나 다른 서비스에 traceId, spanId 전달 불가

→ Feign X-B3-TraceId header에 강제로 넣어서 호출되도록 처리, 최초 시작되는 시점이므로 TraceId만 넣어줘도 무방

카프카 consumer 프로젝트 적용

sleuth는 HTTP Client기반으로 Trace를 생성하는 구조다 보니 kafka consumer가 메시지를 읽을때는 생성하지 못함.

→ 공통 aop로 개발하여 메시지 읽을때 traceId, spanId 생성

 

consumer 트랜잭션

private final Tracer tracer;
   @Before("@annotation(com.ssg.api.collect.kafka.common.annotaion.KafkaLogger)")
   public void printLogging(JoinPoint joinPoint) {
       Span span = tracer.nextSpan().name("span").start();

           MDC.put("traceId", span.context().traceIdString());
           MDC.put("spanId", span.context().spanIdString());
   }

traceId, spanId를 강제 생성 한후 feign header에 생성

public class SsgFeignConfig implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate requestTemplate) {

        requestTemplate.header("Accept", "application/json");
        requestTemplate.header("Content-Type", "application/json;charset=utf-8");
        requestTemplate.header("X-B3-TraceId", MDC.get("traceId"));

        requestTemplate.header(HttpHeaders.CONNECTION, "keep-alive");
    }
}

 

참고

https://docs.spring.io/spring-cloud-sleuth/docs/current-SNAPSHOT/reference/html/

https://cloud.spring.io/spring-cloud-sleuth/2.1.x/single/spring-cloud-sleuth.html#_propagation

 

728x90
반응형