티스토리 뷰
Tomcat 같이 Thread pool을 만들어두고 사용하는 경우, ThreadLocal
사용 시 주의해야하는 점이 있습니다. 바로 Thread 반환 시, ThreadLocal
을 remove
해주어야 한다는 점입니다.
왜 Thread pool을 사용할까요?
Thread pool을 사용하는 경우는 이유가 명확한데요. Thread를 작업 도중 생성하는 것이 시간이 오래 걸리는 비싼 행동이기 때문입니다.
그러므로 특정한 개수(Tomcat의 경우 200개)만큼의 Thread를 미리 만들어두고, 요청이 들어올 때마다 만들어둔 Thread를 이용하도록 합니다. 작업이 끝나면 다시 Thread를 반환하고, 추후 다른 요청을 처리할 때 다시 이용하게 됩니다.
왜 이러한 Thread pool 구조에서 ThreadLocal
을 사용하면 remove
를 해주어야하는 것일까요?
위에서 보셔서 아시겠지만, 정답은 위에 밑줄 표시한 문장에 있습니다. Thread pool에 존재하는 Thread는 시간이 지남에 따라 재활용 될 수 있기 때문입니다.
만약 ThreadLocal
을 비워두지 않았다면, 추후 다시 Thread가 사용될 때 ThreadLocal
에 담아둔 데이터에 접근이 가능해집니다. 이는 보안적으로도 문제가 될 수 있으며, 기능적으로도 불안정한 시스템 구조를 야기할 수 있습니다.
그러므로, ThreadLocal
을 사용하였다면 맨 마지막에 꼭 remove
메서드를 통해 ThreadLocal
을 비워줘야만 합니다.
Spring security 예제
Spring security에서는 SecurityContextHolder
를 이용해 인증정보를 저장해두고 활용하는데요. 기본적인 전략으로 MODE_THREADLOCAL
을 사용합니다. (Reactive의 경우엔 다릅니다. Context를 이용합니다.)
MODE_THREADLOCAL
전략을 사용하게 되면 ThreadLocalSecurityContextHolderStrategy
을 SecurityContextHolderStrategy로서 사용하게 되고, 이 내부에서 SecurityContextHolder로 ThreadLocal
를 사용하게 됩니다.
ThreadLocal
을 사용하고 있으므로 remove
를 해주어야합니다. 이를 clearContext
method를 통해 해주고 있습니다.
Spring security는 Filter chain으로 이루어져 여러 Filter를 통해 인증/인가 과정을 수행합니다. FilterChainProxy
를 통해서 SecurityFilterChain
으로 처리를 위임합니다. 아래 예제 코드를 보시면 FilterChainProxy
에서 filter로 전달하고 마지막 finally
를 통해 context를 비워주고 있습니다.
Conclusion
ThreadLocal
는 한 요청 내 동기화 된 데이터를 이용 함에 있어 매우 편리하게 사용할 수 있습니다. 하지만 사용 시에는 remove
를 통해 비워주는 것을 잊지 맙시다.
'Development > Java, Kotlin, Frameworks' 카테고리의 다른 글
R2DBC를 사용해보자 (2) - CRUD를 만들어보자 (0) | 2022.08.15 |
---|---|
R2DBC를 사용해보자 (1) - 왜 사용할까? (0) | 2022.08.15 |
Stream.toList로 Stream.collect(toList())를 대체해도 되는 걸까? (1) | 2022.05.07 |
[IntelliJ IDEA] Java Stream Debugging (스트림 디버깅) (1) | 2022.05.04 |
Java Memory 이해 & OOME 오류에 관하여 (0) | 2022.04.27 |
- Total
- Today
- Yesterday
- 백준
- java
- python
- hexagonal architecture
- 알고리즘
- boj
- c++
- Istio
- docker
- 비동기
- tag
- Algorithm
- container
- Spring
- WebFlux
- 일상
- 로그
- 하루
- Spring boot
- 클린 아키텍처
- Clean Architecture
- Intellij
- gradle
- Log
- 쿠버네티스
- HTTP
- jasync
- k8s
- MySQL
- Kubernetes
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |