카테고리 없음

spring과 fast api의 동시 요청 처리 차이점 정리

happy_life 2024. 3. 18. 18:16

이번 포스팅에서는 spring boot와 fast api의 동기 처리 차이점을 정리하려고 합니다.

 

 

Spring Boot 에서의 동시 요청 처리

Spring boot 에서는 multi Thread를 사용하여 동시 요청을 처리합니다. 이를 위해 Thread Pool이 존재하는데 그 안에 2개의 Thread가 있다고 가정하겠습니다. 만약 2개의 request가 동시에 온다면 어떻게 될까요? (I/O 관련된 request 1개와 다른 request 1개, CPU는 1개, 다른 Process는 없음)

 

먼저 I/O 관련 request가 0.0001초 빠르게 들어온 경우 1개의 Thread를 할당하고 애플리케이션 계층에서 OS 계층으로 전달됩니다. 이후 OS는 I/O device에 read/write 등을 요청하고 I/O 관련 thread를 block 상태로 전환합니다.

이후 contextSwitching이 동작하여 다른 request를 handling하는 thread가 CPU를 선점하게 됩니다. (물론 상황에 따라 다른 context로 switching이 일어날 수도 있습니다. 복잡한 환경은 생략합니다.) 이후 I/O 가 끝나면 device에서 interrupt를 OS에 주고 다시 I/O thread가 block 상태에 있다가 디스패치되어 running 상태가 된 후 CPU를 선점하게 됩니다. 

 

 

Fast API 에서의 동시 요청 처리

fastApi에서는 하나의 Thread를 사용하여 동시 요청을 처리합니다. request가 발생하면 이것은 task 가 되어 이벤트 루프에 스케줄 됩니다. 만약에 I/O request가 발생하는 경우, 이벤트 루프가 이를 처리하고 I/O 의 완료 여부와 상관없이 non-blocking으로 바로 다른 request를 처리합니다.  await이라는 keyword가 있기때문에 이것이 가능한데 이는 현재(I/O)의 task를 일시 중지하고, 다른 request를 처리하다가 I/O가 완료되었을 때 다시 돌아갈 수 있도록 런타임에서 구현된 것입니다.  

이 과정을 통해 thread간 contextSwitching을 하지 않게 되어 Overhead를 줄이고 빠른 응답속도를 얻을 수 있는 것입니다. 

 

 

Event Loop는 무엇인가?

하나의 Thread에서 여러 요청을 handling 하기 위한 runtime environment입니다. ex) uvicorn

 

Event Loop와 ContextVar

이벤트 루프가 비동기적으로 다른 요청을 처리하기 전에, 기존의 정보를 저장하기 위해 필요한 것입니다. 이것은 운영체제에서 context Switching 전에 직전 context의 정보를 저장하기 위해 사용되는 PCB와 같은 역할을 합니다. 

 

Spring Boot vs Fast API

그렇다면 overhead가 적은 fast api를 사용하는 것이 적절하지 않을까요? 왜 Spring Boot는 여전히 thread Pool과 multi-Thread를 사용하는 것일까요? 원인은 아래와 같습니다.

 

1. Spring은 java 환경입니다. java는 blocking I/O operation 과 멀티 쓰레드를 통해 동시성 문제를 해결합니다. 물론 자바도 업데이트 되어서 non-blocking I/O를 지원하긴 합니다. 이에 Spring WebFlux 등이 존재하는 것입니다. 하지만 대부분의  관련 라이브러리에서 sync 전략을 사용하기 때문에 여전히 Thread Pool 방식을 default로 사용하는 것입니다.

 

2. Spring Boot의 Legacy 때문에 이 프레임워크 자체를 모두 non-blocking으로 migration 하는 것이 어렵습니다. 또한 선택 옵션으로 Spring WebFlux 등을 사용할 수 있으므로 개발자에게 두 가지 옵션을 모두 제공한다고 볼 수 있습니다. 

 

3. I/O와 관련하여 asnyc 전략이 이점을 갖는 것은 사실이나, 이것이 모든 관점에서 sync전략보다 우세한 것은 아닙니다.