TIL(사전캠프)

리액티브. (2024-07-08)

note994 2024. 7. 8. 19:25

1. Spring Framework에서의 Blocking I/O와 Non-Blocking I/O

Spring Framework는 Java 백엔드 개발자에게는 반드시 학습해야 되는 중요한 기술이다. 특히 Spring MVC 기반의 개발 방식은 10여 년에 걸쳐 진화를 거듭하며 익숙해진 개발 방식이다. 하지만 Spring MVC 기반으로 개발된 웹 애플리케이션에서의 요청 처리가 이제는 버거울 수 있는 시대가 되었다.

 

그 이유는 Spring MVC 기반의 웹 애플리케이션이 바로 Blocking I/O 방식을 사용하기 때문이다.

 

스마트폰이나 태블릿 등의 휴대기기, IOT 기술의 발전으로, Blocking I/O 방식의 애플리케이션이 감당하기 힘들 만큼의 클라이언트 요청 트래픽이 발생하는 상황이 많아졌다. 

 

이런 문제점을 극복하기 위해서 Spring MVC의 대안으로 나온 것이 바로 Spring WebFlux이다.

 

Spring MVC와 Spring WebFlux의 가장 큰 차이점은 Blocking I/O 방식이냐, Non-Blocking I/O 방식이냐 이다. 또한 서블릿 컨테이너 기반의 Spring MVC는 요청당 하나의 스레드를 사용하기 때문에 대량의 요청을 처리하기 위해서 과도한 스레드를 사용함으로써 CPU 대기 시간이 늘어나고 메모리 사용 시 오버헤드가 발생한다.

 

반면에 Spring WebFlux는 Netty같은 비동기 Non-Blocking I/O 기반의 서버 엔진을 사용함으로써 적은 수의 스레드로 많은 수의 요청을 처리하기 때문에 CPU와 메모리를 효율적으로 사용할 수 있어 결과적으로 적은 컴퓨팅 파워로 고성능의 애플리케이션을 운영할 수 있게 해준다.

 

Blocking I/O와 Non-Blocking I/O에 대한 예제 코드를 실행해 보면 둘의 차이점을 확실히 알 수 있다.

 

이제 볼 예제 코드는 [그림 3-1] Blocking I/O 예시와 [그림 3-3] Non-Blocking I/O 예시에서 설명한 동작 과정을 코드로 옮긴 것이라고 보면 된다.

 

먼저 Blocking I/O 예제 코드부터 살펴보자

코드3-1 Blocking I/O 본사 API 서버(SpringMvcHeadOfficeController.java)

 

코드 3-1은 [그림 3-1] Blocking I/O 예시에서 본사 API 서버에 해당되는 코드이다.

 

코드 자체는 Spring MVC 기반의 코드이기 때문에 코드 자체가 잘 이해되지 않는다면 Spring MVC 레퍼런스를 살펴보길 바란다.

https://docs.spring.io/spring-boot/reference/web/servlet.html#web.servlet.spring-mvc

 

Servlet Web Applications :: Spring Boot

For servlet application, Spring Boot includes support for embedded Tomcat, Jetty, and Undertow servers. Most developers use the appropriate “Starter” to obtain a fully configured instance. By default, the embedded server listens for HTTP requests on po

docs.spring.io

 

[그림 3-1]에서 본 것처럼, 본사 API 서버가 클라이언트 PC로부터 도서 정보 조회 요청을 받으면 요청에 해당하는 도서 정보를 조회하기 위해 지점 API 서버로 다시 요청을 보낸다(29 ~ 30번 라인)

 

이 부분에서 아마도 Blocking I/O가 발생하여 현재 스레드가 차단될 거라는 예상을 해볼 수 있다.


코드 3-2 Blocking I/O 지점 API 서버(SpringMvcBranchOfficeController.java)

 

코드 3-2는 [그림 3-1] Blocking I/O 예시에서 지점 API 서버에 해당되는 코드이다.

 

지점 API 서버는 애플리케이션이 실행될 때 내부적으로 Map에 샘플 도서 정보를 미리 저장해 둔다. 원칙적으로 데이터베이스 같은 저장소에 저장된 도서 정보를 조회하는 것이 맞지만 편의상 Map에 저장한 것이다.

 

코드 3-1과 3-2의 키 포인트는 클라이언트 PC의 요청을 전달받은 Spring MVC 기반 애플리케이션의 현재 스레드 내에서 또 다른 요청 전송으로 인한 네트워크 I/O가 발생했을 때 현재 스레드가 차단되느냐 하는 것이다.

 

차단이 되는지 알아보기 위한 가장 쉬운 방법은 작업 스레드 내에서 시간이 오래 걸리는 작업을 임의로 만들어 주는 것이다.

 

코드 3-2의 15번 라인이 그러한 처리를 해 주는 코드이다. Thread.sleep(5000)을 통해 작업 스레드의 실행을 5초(5000ms) 정도 지연시킴으로써 오래 걸리는 작업인 것처럼 시뮬레이션 할 수 있다.

 

'TIL(사전캠프)' 카테고리의 다른 글

리액티브. (2024-07-10)  (0) 2024.07.10
리액티브. (2024-07-09)  (0) 2024.07.09
Java. 배운거 기록하기(2024-07-05)  (0) 2024.07.05
리액티브.(2024-07-04)  (0) 2024.07.04
리액티브. (2024-07-03)  (0) 2024.07.03