Java Virtual Thread (9), Spring Boot에서 Virtual Thread 사용하기
spring:
output:
ansi:
enabled: ALWAYS
threads:
virtual:
enabled: true
task:
scheduling:
thread-name-prefix: mySch-
yml 파일에 spring.thread.virtual.enavled = true 로 설정해주면 스프링이 기존 thread pool 의 동작을 모두 virtual thread pool 로 대체해준다.
RestController 에서 사용하는 Tomcat의 Thread가 어떻게 Virtual Thread로 동작하는지 살펴보자.
@GetMapping("/sleep")
public void sleep() throws InterruptedException {
log.info("1) counter: {}, thread: {}", counter.incrementAndGet(), Thread.currentThread());
Thread.sleep(5000);
//log.info("2) thread: {}", Thread.currentThread());
}
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0")
테스트를 위해 위 의존성도 추가해주자.
localhost:8080/swagger-ui/index.html 에 들어가보면 swagger 페이지에서 테스트가 가능하다.
/sleep 을 실행하여 호출해보면 아래와 같은 로그를 확인해 볼 수 있다.
1) counter: 1, thread: VirtualThread[#72,tomcat-handler-11]/runnable@ForkJoinPool-1-worker-10
해석해보면 VirtualThread 이고, 이름은 tomcat-handler-11 이며, ForkJoinPool-1-worker-10 은 virtual thread가 사용하는 플랫폼 스레드 혹은 캐리어 스레드의 정보이다.
ForkJoinPool-1-worker-10 이라는 플랫폼 스레드 (캐리어 스레드)를 통해 수행되고 있는 것이다.
sleep 전/후로 다른 플랫폼 스레드 (캐리어 스레드)를 사용하는 것은 가능할까?
예를들어 sleep 전에는 ForkJoinPool-1-worker-10을 사용하고 sleep 후에는 ForkJoinPool-1-worker-11를 사용하도록 하는 것이 가능할까.
항상 같은 플랫폼 스레드를 사용해야하는 것인지, 다른 플랫폼 스레드를 사용할 수 있는 것인지 고민해보자.
CPU 가 여유로울 땐 거의 동일하다. 그렇지 않은 경우 다른 결과가 나온다. Jmeter 를 통해 부하를 줘보자.
(100개의 request 생성)
플랫폼 스레드가 부족하거나 CPU가 바쁠 땐 다른 플랫폼 스레드를 사용하게 된다. sleep 전에 할당된 스레드가 있지만 sleep 때문에 기존 플랫폼 스레드가 언 마운트된다. sleep 이 끝나면 그때 가능한 플랫폼 스레드 중 하나를 불러오게 된다.
...
정리
1) Java 기본 스레드 풀을 가상 스레드로 설정하기 위해 yml 파일에 아래와 같은 설정이 필요하다.
- spring.thread.virtual.enabled = true
2) thread: VirtualThread[#72,tomcat-handler-11]/runnable@ForkJoinPool-1-worker-10
- VirtualThread 를 사용하고 있으며, 이름은 tomcat-handler-11 이다.
- ForkJoinPool-1-worker-10 은 Virtual Thread 가 사용하고 있는 플랫폼 스레드(캐리어 스레드)이다.
3) sleep 전/후로 동일한 플랫폼 스레드를 사용할수도 있고 사용하지 않을수도 있다.
- 요청이 많아 플랫폼 스레드가 부족하거나 CPU가 바쁠땐 다른 플랫폼 스레드를 사용하게된다.
- 요청 100개를 넣었을때 sleep 전에는 2,5 플랫폼 스레드가 사용되고 sleep 후에는 2, 5, 7 플랫폼이 사용된 것을 확인하였다.
궁금한 것
1) tomcat-handler-11 (가상 스레드) 와 ForkJoinPool-1-worker-10 (플랫폼 스레드) 차이
2) tomcat-handler-11 여러개 설정가능?
3) ForkJoinPool-1-worker-10 는 자동으로 할당되는 것인가? 개수를 설정할 수는 없는건가?