카테고리 없음

Java Virtual Thread (9), Spring Boot에서 Virtual Thread 사용하기

개발정리 2024. 6. 23. 16:25
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 는 자동으로 할당되는 것인가? 개수를 설정할 수는 없는건가?