멋사 부트캠프

[멋사 부트캠프] Day10 - ThreadLocal

sagecode 2025. 6. 30. 12:37

웹 서비스에서는 누군가 웹사이트에 요청을 보내면, 서버는 그 요청을 처리하기 위해 작업 스레드를 하나 배정한다. 그런데 이 서버는 동시에 수많은 요청을 받기 때문에, 여러 스레드가 각기 다른 동시 요청을 처리하고 있다. 이때 각 요청마다 사용자 정보, 고유 ID 같은 데이터를 계속 가지고 다녀야 하는데 그걸 매번 메서드 인자로 전달하는 건 너무 번거롭고 복잡하다.

 

이럴 때 사용하는 게 바로 ThreadLocal이다.

 

ThreadLocal

TraceID란?

TraceID는 사용자의 하나의 요청이 시스템을 통과할 때 발생하는 전체 처리 흐름을 유일하게 식별할 수 있는 ID 단위의 기록이다.

아래 예시를 보자.

Trace ID: abc-123
- 시작 시간: 10:00:00
- 전체 처리 시간: 128ms
- 총 5개 작업(SPAN)
- 성공 여부: OK

Trace는 이 하나의 HTTP 요청 전체를 감싸고 추적한다.

 

TraceHolder.java

package org.example.backendproject.threadlocal;

// 이 클래스는 스레드마다 고유한 요청 ID를 저장하고 꺼내는 역할을 합니다.
public class TraceHolder {
    // TraceId란 하나의 요청을 고유하게 식별하는 ID

    private static final ThreadLocal<String> threadLocal = new ThreadLocal<>();

    // ThreadLocal
    public static void set(String traceId) {
        threadLocal.set(traceId);
    }
    public static String get() {
        return threadLocal.get();
    }

    // 하나의 요청이 끝났을 때 TreadLocal에 저장된 값을 지우기 위한 메서드
    public static void clear() {
        threadLocal.remove();
    }
}
  • ThreadLocal<String> 을 통해서 TraceID를 스레드 단위로 보관한다.
  • Thread마다 고유한 TraceID가 하나씩 존재한다 -> 요청간 데이터가 섞이지 않는다.

 

  • 요청 처리가 끝나면 traceId를 지워서 메모리 누수 방지한다.
  • 스레드는 재사용되기 때문에 안 지우면 다음 요청에서 이전 traceId가 남아 있는 버그가 발생 가능하다.

 

LogAspect.java