Virtual Thread Spring에 적용해 보기

Yukicow·2024년 3월 25일
0
post-custom-banner

이전에 Virtual Thread에 대한 내용을 정리해 보았는데,
실제로 Blocking이 발생하는 상황에서 얼만큼의 성능 개선이 있는지 알아 보기 위해 간단하게 적용해 보고자 한다.

Platform Thread


@RestController
public class VirtualController {


    @GetMapping("/block")
    public ResponseEntity<Object> fetchBlockRequests() throws InterruptedException {
        Thread.sleep(2000);
        return ResponseEntity.ok().build();
    }
}

간단하게 요청 마다 2초의 I/O Block이 발생한다는 가정으로 Thread.sleep을 2초 주었다.

최대 스레드 수는 기본값인 10개이며 커넥션 Timeout을 넉넉하게 설정하여 에러가 발생하지 않도록 하고 1초 동안 1000번의 요청을 10번 보내 보았다.

99.3TPS로 약 초당 100번의 요청을 처리할 수 있다.



Virtual Thread

Virtual Thread를 적용하기 위해서는 설정이 필요하다.

필자는 I/O Blocking이 많이 발생하는 요청들을 Platform Thread로 처리하는 것과 Virtual Thread로 처리하는 것을 비교하는 것이기 때문에 Tomcat에 대한 설정만을 다룬다.

1. 적용 (Spring boot 3.2 이상)

Spring boot 3.2 이상부터는 간단하게 application.yml에 아래와 같은 설정을 추가하여 적용이 가능하다.

spring:
	threads:
    	virtual:
        	enabled: true

2. 적용 (Spring boot 3.x)

Virtual Thread를 적용하기 위해서는 설정이 필요하다.

Spring boot 3.2 이상부터는 간단하게 application.yml에 아래와 같은 설정을 추가하여 적용이 가능하다.

@Configuration
public class ThreadConfig {

	@Bean
	public TomcatProtocolHandlerCustomizer<?> protocolHandlerVirtualThreadExecutorCustomizer() {
		return protocolHandler ->
			protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
	}
}

문제(?)

위와 같은 설정을 사용하면 모든 요청이 Virtual Thread로 동작하는 듯 하다.

요청에 따라서 Platform Thread와 Virtual Thread를 구분하고 싶은데 Tomcat이 이 부분을 지원을 해 주어야 하는 문제인가(?) 싶다.



실행

위와 똑같이 1초 동안 1000번의 요청을 10번 보내 보았다.

473.4TPS로 초당 처리 가능한 요청 수가 약 4.8배 정도 증가한 것을 확인할 수 있다.



의문

Platform Thread를 Virtual Thread 만큼 많이 생성한다면 얼만큼의 성능 차이가 있는지 궁금하여 자원을 최대한 활용한 상황에서의 성능 테스트를 진행해 보았다.

( 물론 로컬 컴퓨터의 최대 자원이 어느정도인지 감이 잘 안 와서 대충 높게 설정하고 실행해 보았다. )

톰캣의 최대 스레드 개수를 2000개로 설정하고 Platform Thread를 사용해서 4천번의 요청을 2초 동안 10번 보내 보았다.

914.9TPS로 스레드 수를 높이면 확실히 Platform Thread라도 높은 성능을 보이는 것을 알 수 있다.

필자는 같은 조건에서 Virtaul Thread를 사용하면 Virtual Thread의 태스크를 분담할 스레드가 많아지니 한 번에 더 많은 요청 처리가 가능 할 거라는 가정을 내렸다.

그래서 같은 조건으로 Virtual Thread를 활성화하고 요청을 보내 보았다.

약 2배 정도의 높은 TPS가 나오는 것을 확인할 수 있다.

더 극단적인 예시로 같은 조건에 8000번의 요청을 4초에 걸쳐 10번 보내 보았을 때, Platform Thread의 경우 서버가 모든 요청에 대해 응답을 제대로 반환하지 못 하고 죽어버리는 상황이 발생했는데, Virtual Thread는 문제 없이 동작했으며 아래와 같이 높은 TPS를 보여 주었다.

이로서 같은 조건에서 Blocking 상황이 발생하는 요청을 Virtual Thread를 사용할 경우 더 많은 요청 처리가 가능하다는 것이 확인되었다.

아마 자원을 MAX로 활용한 상황에서 테스트를 하면 약간의 차이가 있을 수 있지만 Virtual Thread가 너 높은 처리량을 보여준다는 사실 자체는 크게 변하지 않을 듯 하다.

( 정확한 측정을 위해서는 이런 단순한 테스트 보다 정밀한 테스트가 필요하겠지만, 단순히 이론적인 부분을 확인해 본 정도로 이해하면 좋을 것 같다. )



정리

실제로 Blocking이 발생하는 상황에서 Virtual Thread가 효과적으로 동작한다는 것을 확인했다.

나중에는 @Async와 활용하거나 Virtual Thread를 직접적으로 사용하여 성능 개선할 수 있는 부분을 찾아 적용해야겠다.

profile
자료를 찾다 보면 사소한 부분에서 궁금한 부분이 생기도 한다. 똑같은 복붙식 블로그 때문에 시간만 낭비되고 시원하게 해결하지 못 하는 경우가 많았다. 그런 부분들까지 세세하게 고민하고 함께 해결해 나가고자 글을 작성한다. 혼자서 작성하는 블로그가 아닌 함께 만들어 가는 블로그이다. ( 지식 공유를 환영합니다. )
post-custom-banner

0개의 댓글