webMVC
스프링의 WebMVc는 동시 접속 사용자 처리를 위해 블로킹 IO 모델을 활용합니다. 이는 처리 가능한 동시 접속자의 수만큼 스레드를 생성해 각각의 스레드가 요청이 완료될 때까지 점유 되어있는 상태로 존재하며 클라이언트에게 요청에 대한 응답을 돌려줄 때 해당 스레드가 다시 가용한 상태로 전환되는 방식입니다(Tomcat의 Thread Pool)
webFlux
스프링 WebFlux는 비동기, 논블로킹 형태로 구성되어 있습니다.
클라우드 환경을 기반으로 한 IT 서비스 인프라 환경이 늘어나기 시작하면서 웹 서비스아키텍처 구축 시 더 적은 자원으로 더 빠르게 서비스를 제공하려는 수요가 늘어나기 시작했고, Node.js에서는 이벤트 루프를 활용한 Non-Blocking IO를 선보이면서 웹 서비스 아키텍처에 새로운 패러다임이 제시되었습니다.
Node.js의 성공을 통해 자바 진영에서도 논블로킹 IO 모델에 대한 필요성이 꾸준히 제기되었다. 스프링 프레임워크 5버젼부터 논블로킹 IO를 활용한 웹 프레임워크를 구축하는 도구를 WebFlux라는 이름으로 지원하기 시작하였습니다.
Blocking IO
블로킹 IO 방식은 클라이언트로부터 요청이 발생한 시점부터 서버가 이를 처리하고 클라이언트에게 응답을 주기 전까지 대기하는 구조이다. 하나의 스레드가 클라이언트의 요청을 처리하는 동안에는 다른 서비스를 수행할 수 없는 블로킹상태가 된다.
Non-Blocking IO
논블로킹 IO 방식은 클라이언트가 서버에 요청을 전달한 뒤 대기하지 않고 다른 처리를 수행하는 구조이다.
처리가 완료된 뒤에는 미리 등록된 콜백 함수를 호출하여 후 처리를 진행한다. 이러한 방식은 요청을 받고 해당 요청에 대한 결과를 리턴하는 과정에서 다른 태스크를 수행할 수 있기 때문에 다수의 스레드 풀을 생성할 필요가 없다.
반응형 프로그래밍(Reactive Programming)
반응형이라는 용어는 IO 이벤트에 반응하는 네트워크 컴포넌트, 마우스 또는 키보드 이벤트에 반응하는 UI 컨트롤러 등 이벤트에 반응하는 프로그래밍 모델을 의미합니다. 이런 의미에서 논블로킹 IO는 반응형이라고 볼 수 있는데, 이는 논블로킹 IO는 작업이 완료되거나 데이터가 사용 가능한 이벤트에 반응할 수 있는 구조를 갖추기 때문입니다.
그럼 다시 스프링 WebMVC로 돌아와서, 스프링 WebMVC는 블로킹 방식의 웹 서비스를 구현하기 위해 제공되는 스프링 프레임워크의 라이브러리 입니다. MVC는 Model-View-Controller 디자인 패턴의 약어이며, 클라이언트로 부터의 요청은 Dispatcher Servlet을 통해 Controller로 전달되며 이 때 동시 접속을 위한 사용자의 수만큼 스레드가 생성되는 구조 입니다.
반면 스프링 WebFlux는 논블로킹 IO 처리를 위해 제공되는 스프링 프레임워크의 라이브러리입니다. 스프링 프레임워크 5 버전부터 제공되기 시작하였으며 반응형 프로그래밍(Reactive Programming)을 위한 API 스펙을 구현하였습니다.
스프링 WebMvc는 블로킹 IO 이기 때문에 하나의 호출마다 한개의 thread를 생성합니다(Tomcat을 사용할 시에는 Thread Pool에서 한개의 thread를 꺼내옵니다), 호출마다 한개의 스레드를 생성하기 때문에 요청이 적은 서비스에서는 최적의 성능을 낼 수 있습니다.(병렬 작업의 장점이기도 합니다)
반면 논블로킹 IO의 경우 블로킹 IO와는 달리 요청마다 thread를 생성하지 않기 때문에 부하가 발생하지 않습니다.
또한 Context-Switching이 발생하지 않습니다. 논블로킹 IO는 요청을 받는 부분이 Single thread이기 때문에 요청마다 thread를 생성하지 않으며, 그렇기 때문에 Context-Switching을 걱정하지 않아도 됩니다.
WebMVC 와 WebFlux 언제쓰는게 좋을까?
먼저 WebMVC는 Servlet기반으로 이루어져 있고, WebFlux는 Reactive기반으로 이루어져 있기 때문에, WebMVC는 블로킹 IO 형태로 된 Dependency를 사용하는 경우에 적합하며, WebFlux를 사용하더라도 ServletAPI를 사용하게 된다면 순간 Blocking으로 바뀌게 되기 때문에 Servlet을 사용하는 것이 더 어울립니다.
Servlet에서 Reactive를 사용하는 방법도 있습니다. 예를 들어 MicroService 환경에서는 각 api들 끼리 네트워크 통신(RESTAPI)을 통해 요청을 주고받기 때문에, 다른 Service로 요청을 보내거나 데이터를 받아올 때 Reactive를 사용하면 좋을 것 입니다.
이와 관련하여 MicroService 에서 webFlux가 가지는 장점에 대해 정리한 포스트를 참고하셔도 좋을 것 같습니다.
'프로그래밍 > Spring' 카테고리의 다른 글
mock() vs @Mock vs @MockBean 이제 그만 헷갈리자! (0) | 2023.06.25 |
---|---|
Spring Data Common 모듈 에서의 디자인 패턴 (2) | 2023.05.27 |
Micro Service에서 WebFlux의 장점 (0) | 2022.12.28 |