Rlog

Spring-Cloud-Sleuth 비동기 요청시 서버간 TraceId 보존하는 방법 본문

Spring

Spring-Cloud-Sleuth 비동기 요청시 서버간 TraceId 보존하는 방법

dev_roach 2022. 4. 27. 20:36
728x90

방법을 찾게 된 계기

Java 나 Kotlin 에서는 ThreadLocal 을 이용가능하다. 

주로 Logback 의 MDC 에서도 이 ThreadLocal 을 이용해서 하나의 스레드내에서 동작하는 특정 값을 로깅하기 위해 이용한다.

 

Slueth 또한 MDC 를 이용하는데 MDC 에 traceId 와 spanId 를 저장한다.

traceId 를 어떻게 Thread 에서만이 아닌 서로 다른 서버에서도 똑같은 값으로 주어 좀 더 흐름을 찾기 쉽게 만들까? 라는 고민을 하다가 아래와 같이 삽질을 하게 되었다.

예시

백문이 불여일타라고 예시코드로 시작해보자.

일단 ThreadPoolTaskExecutor 를 테스트를 위해서 대충 만들어보자.

이제 Async 에서는 위의 ThreadPoolTaskExecutor 를 이용해서 Async 작업을 처리할 것이다.

위의 클래스 두개를 만들어놓자. 하나는 Async 로 FunctionTemplate 을 돌릴거고, 하나는 Sync 로 FunctionTemplate 을 수행할 것이다. 나의 다른 서비스로 한번 요청을 보내보자.

열번 요청을 보내고 나서 로그를 한번 확인해보자. 모두 TraceId 가 같은 것을 확인할 수 있다.

그럼 받는 쪽도 확인해보자.

받는 쪽의 TraceId 는 같아야 하지만 모두 다른 것을 알 수 있다.

어떻게 해야지 하나의 요청에서 비동기 요청이라도 TraceId 를 같게할 수 있을까?

일단 기본적으로 Sleuth 는 MDC Context 에 traceId 와 spanId 를 저장한다.

Sleuth 는 기본적으로 B3-Propagation 을 통해서 서버간 정보를 전파할 수 있다.

따라서 아래와 같이 코드를 작성하면 된다.

 

헤더에 TraceId 와 spanId 를 넣어주는 것이다. spanId 는 별도로 안넣어줘도 된다. 개인의 선택에 따라 판단하면 될듯 하다.

해결

첫번째 서버

두번째 서버

느낀점

다른 회사에서나 다른 팀은 ThreadPool 을 Custom 하는 경우도 많은데, 굳이 Decorator 를 커스텀하기 보다는 Sleuth 자체의 B3-Propagation 정책을 알기만 하면 단순하게 Request-Header 를 통해서 해결 가능하다.

이번 계기로 회사 로그 강화도 하고, Sleuth Repository 에 컨트리뷰션도 할 수 있게 됬다.