반응형
a thousand hearings aren’t worth one seeing, and a thousand seeings aren’t worth one doing
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))
)
}
부하 테스트
기존 Tomcat Thread를 활용한 방식
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는 다른 작업을 처리할 수 있는 구조라서 위와 같은 결과를 볼 수 있다고 보면 됩니다.
728x90
'🍃 Spring' 카테고리의 다른 글
[Spring] R2DBC DatabaseClient 잘 사용하기 (0) | 2024.09.19 |
---|---|
[Spring] Webflux에 Mongo 연결(+Kubernetes) (0) | 2024.09.05 |
@Autowired HttpServletRequest 사용하기(+RequestContextHolder, ThreadLocal) (0) | 2023.11.10 |
JUnit 문법 (0) | 2023.08.26 |
@WebMvcTest에 대한 올바른 사용법 및 시행착오 (0) | 2023.08.22 |