공부 기록/Spring

Spring WebFlux란 뭘까

뵤옹 2023. 3. 30. 17:23

Spring WebFlux란?

Spring 5에서 새롭게 추가된 모듈로, client, server에서 reactive 스타일의 애플리케이션의 개발을 도와준다.

WebFlux는 기존의 Servlet API 기반으로 구축된 웹 프레임 워크인 Spring MVC를 대체할 수 있는 웹 프레임워크이다.

WebFlux는 Spring reactive-stack web framework이며, none-blocking에 reactive stream을 지원한다.

 

❓ block / none-blocking 웹 스택

1. Block 방식

사용자가 함수를 호출하면 호출된 함수에 제어권이 이동되면서 함수의 로직이 실행되고 제어권을 가지고 있는 함수가 결과를 반환할 때까지 제어권을 가지고 있다가 제어권과 결과값을 같이 전달하는 방식

 

2. Non-Block 방식

사용자가 함수를 호출하면 제어권을 호출되는 함수에 넘기지만 해당 제어권을 호출된 함수가 결과값이 나오기 전에 바로 호출자에게 넘긴다.

따라서 호출자는 결과를 기다리지 않고 다음 함수에게 제어권을 넘기면서, 제어권이 결과와 의미가 없는 방식이다.

(이렇게 정리해보니 제어권을 가지고 동기, 비동기 같은 느낌이다.)

 

❓ Reactive-stack Webframework이란 뭘까

이에 대해 알기 위해 reactive programming을 먼저 알아보자.

reactive programming은 변화의 전파와 데이터 흐름과 관련된 선어적 프로그래밍 패러다임이다.

 

- 변화의 전파와 데이터 흐름

: 데이터가 변경될 때마다 이벤트를 발생시켜서 데이터를 계속적으로 전달한다.

 

- 선언적 프로그래밍

: 실행할 동작을 구체적으로 명시하는 명령형 프로그램과 달리 선언형 프로그램은 단순히 목표를 선언한다.

 

reactive programming을 하면 아래와 같은 이점을 얻을 수 있다.

1. 간결해진 Thread 사용

2. 간단한 비동기 연산

3. 계속되는 Call back 제거

 

 

Spring MVC vs. Spring WebFlux

Spring MVC

- 동기식 blocking 방식을 사용한다.

- 사용자의 요청이 들어올 때마다 Thread를 생성하여 처리한다.

- 보통은 요청시마다 스레드를 생성, 삭제해주면 일정한 리소스가 지속적으로 소모되므로 스레드를 미리 생성해 저장해두는 Thread Pool을 생성해 사용한다.

- 요청이 들어오면 그 요청을 큐에 쌓고 순서에 따라서 스레드를 하나 점유해 요청을 처리한다.

- 동시 다발적으로 스레드 수를 초과하는 요청이 발생한다면 계속해서 요청이 큐에 대기하게 되는 Thread Pool Hell 현상이 발생할 수 있다.

- Tomcat 기반 Jetty 등을 기반으로 동작

 

Spring WebFlux

- 요청을 처리하는 방식이 Event-Driven 방식이고 비동기식 non-blocking이다.

- WebFlux는 이벤트 루프가 돌아서 요청이 발생할 경우, 그것에 맞는 핸들러에게 처리를 위임하고 처리가 완료되면 callback 메소드 등을 통해 응답을 반환한다. (→이 점 때문에 단점이 발생하는게 아닐까라는 생각)

- 이 방식의 경우 요청이 처리될 때까지 기다리지 않기 때문에 Spring MVC에 비해 사용자의 요청을 대량으로 받아낼 수 있다는 장점이 있다.

- react library와 Netty를 기반으로 동작

 

 

Spring WebFlux를 사용하는 이유

1. 비동기, noe-blocking 방식의 reactive 개발에 사용된다.

2. 서버 프로그램이 효율적으로 동작해서 cpu, thread, memory에 자원을 낭비하지 않고 효율적으로 동작하는 고성능 웹 애플리케이션을 개발할 수 있다.(최소한의 스레드와 하드웨어 자원 사용)

 

 

Spring WebFlux의 단점

Webflux는 비동기식 Non-blocking I/O 방식을 활용하기 때문에 Blocking 코드가 있다면 성능이 떨어진다. Blocking I/O를 일으킬 수 있는 코드는 log 출력, map 함수 사용 등이 있다.

map 함수는 동기식 함수를 적용하여 0~1개의 아이템을 변경하는 메서드이기 때문이다. map 함수를 사용해야 할 경우, flatmap을 사용하여 비동기식으로 아이템을 변경해주는 것이 좋다.

원래는 Java에서 Non Blocking을 지원하는 DB Driver가 없었지만, 현재는 R2DBC를 사용하여 Java에서도 Non Blocking으로 DB에 접근할 수 있게 되었다.

 

 

 

 


참고

https://devuna.tistory.com/108

https://thalals.tistory.com/381

https://youtu.be/I0zMm6wIbRI