-
[Spring] 가상 스레드를 이용한 부하테스트카테고리 없음 2024. 10. 27. 23:00
Spring Property 설정
spring.threads.virtual.enabled=true server.tomcat.threads.max=1 server.tomcat.threads.min-spare=1
Spring에서 JDK 21을 이용할 때 가상 스레드를 활용하기 위해서는 spring.threads.virtual.enabled=true를 활성화해줍니다.부하테스트를 위해 Thread는 1개로 유지합니다.
코드 작성
@GetMapping("/test") public String test() throws InterruptedException { Thread.sleep(50); return "test"; }
간단히 위와 같은 Controller Method 하나를 작성해보고 Gatling에 Scala 코드로 동시 1000번 요청을 진행하는 방식으로 작성한 뒤 부하 테스트를 진행합니다.
package test import scala.concurrent.duration._ import io.gatling.core.Predef._ import io.gatling.http.Predef._ import io.gatling.jdbc.Predef._ class RecordedSimulation extends Simulation { val httpProtocol = http("testSimaulation") .get("http://127.0.0.1:8080/test") .header("Client-Version", "1") val scn = scenario("Scenario1") .exec(httpProtocol) setUp( scn.inject(atOnceUsers(1000)) ) }
부하 테스트
1) 기존 Tomcat Thread를 활용한 방식
2) Virtual Thread를 활용한 방식
기존 MVC 작업은 Tomcat Thread 1개가 Sleep에 들어감에 따라 Sleep이 끝나야만 그 다음 작업이 처리 되므로 1000번째 요청인 하위 99퍼센트 요청은 55초째에 마무리된 것을 확인할 수 있습니다.
(Thread Sleep을 50ms로 줬으니 50ms * 1000 = 50000ms)
하지만 Virtual Thread를 사용한 방식은 하위 99퍼센트의 요청도 0.4초안에 끝나는 것을 확인할 수 있습니다.왜 이런걸까?
가상 스레드 개념은 JVM에서 사용하는 Thread에 여러개의 가상 스레드를 붙인 뒤 kernel에 넘겨서 사용하는 개념입니다.
그러므로 가상 스레드는 OS Thread 내에서 실행됩니다.
하지만 가상 스레드에서 실행되는 코드가 블로킹 I/O 작업을 호출하면 자바 런타임은 다시 시작될 수 있을 때까지 가상 스레드를 일시 중지합니다.
그럼 OS Thread와 연결 됐었던 가상 스레드는 중지 상태에 돌아가지만 OS Thread는 다른 작업을 처리할 수 있는 구조라서 위와 같은 결과를 볼 수 있다고 보면 됩니다.