방법을 찾게 된 계기
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 에 컨트리뷰션도 할 수 있게 됬다.
'Spring' 카테고리의 다른 글
WebFlux 에서 ResponseBody 에 Mono, Flux 를 사용하는 이유 (0) | 2022.08.11 |
---|---|
어떻게 Service Layer 간 Transaction Session 을 공유할 수 있을까? (0) | 2022.06.06 |
오늘자 삽질 - Spring Kafka (1) | 2022.04.13 |
기존에 있던 Object 를 Bean 으로 등록하는 방법 (0) | 2022.04.05 |
[JPA] Transactional read only 일때 성능상 이점 (0) | 2022.03.21 |