본문 바로가기
스프링/SpringBoot

[Spring Boot 3.5] WebFlux 버리고 가상 스레드(Virtual Threads)로 갈아타야 하는 이유 (성능 비교 및 주의사항)

by 공부 안하고 싶은 사람 2026. 2. 26.
반응형
Java & Spring Ecosystem 2026

WebFlux의 시대는 끝났는가?
Spring Boot 가상 스레드 실전 가이드

 

안녕하세요, code-resting입니다. 과거 우리는 수만 개의 동시 요청을 처리하기 위해 WebFlux(Netty)라는 다소 복잡한 비동기 모델을 선택해야만 했습니다. 하지만 Java 21에서 정식 도입되고 Spring Boot 3.2+를 거쳐 3.5에 안착한 가상 스레드(Virtual Threads)는 이 패러다임을 완전히 바꾸어 놓았습니다.

1. Platform Thread vs Virtual Thread

기존의 전통적인 스레드 모델인 Platform Thread는 OS 스레드를 래핑한 구조로, 생성 비용이 크고 메모리 점유율(스레드당 약 1MB)이 높아 수천 개 이상의 스레드를 유지하기 어려웠습니다.

구분 Platform Thread Virtual Thread
관리 주체 OS (Kernel) JVM
생성 비용 매우 높음 (Context Switch 발생) 매우 낮음 (일반 객체 수준)
I/O 처리 Blocking 시 스레드 낭비 Blocking 시 스레드 양보(Unmount)

2. Spring Boot 3.5 적용 및 성능 최적화

설정은 간단하지만, 그 내부 동작은 강력합니다. application.yml 설정 한 줄로 모든 서블릿 요청과 @Async 처리를 가상 스레드로 전환할 수 있습니다.

# application.yml
spring:
  threads:
    virtual:
      enabled: true # 모든 TaskExecutor를 가상 스레드로 대체

이렇게 설정하면, 톰캣(Tomcat)은 요청당 하나의 가상 스레드를 할당합니다. 내부적으로 I/O 작업(DB 조회, API 호출 등)이 발생하면 가상 스레드는 실제 OS 스레드를 점유하지 않고 '양보' 상태가 되어 다른 작업을 처리할 수 있게 합니다.

3. 도입 전 반드시 알아야 할 주의사항 (Pinning 문제)

가상 스레드가 무조건적인 마법은 아닙니다. 가장 주의해야 할 점은 Pinning 현상입니다.

  • synchronized 블록 사용 지양: 가상 스레드 내에서 synchronized를 사용하면 스레드가 캐리어(OS) 스레드에 고정되어 성능이 급격히 저하됩니다. 대신 ReentrantLock을 사용하세요.
  • ThreadLocal 남용 금지: 수백만 개의 가상 스레드가 생성될 수 있으므로, 각 스레드마다 무거운 객체를 ThreadLocal에 담으면 메모리 부족(OOM)이 발생할 수 있습니다.
  • No Pooling: 가상 스레드는 재사용하는 물건이 아닙니다. Thread Pool을 만들지 말고 필요할 때마다 생성하고 버리세요.

💡 결론: 2026년의 백엔드 전략

CPU 연산 위주의 작업이 많다면 기존의 스레드 방식이 유리할 수 있지만, 대부분의 비즈니스 로직(CRUD, 외부 API 연동) 환경에서는 가상 스레드가 정답입니다. 복잡한 WebFlux의 연산자(Mono, Flux) 체인에서 벗어나, 가장 직관적인 코드로 최상의 퍼포먼스를 내보세요.

© 2026 code-resting. All rights reserved.
더 많은 백엔드 인사이트를 위해 구독공감 부탁드립니다!

 

반응형

댓글