Junuuu 2023. 12. 2. 00:01

Webflux란?

Spring 5에서 추가된 웹 프레임워크이며 클라이언트/서버에서 reactive programming 기반의 애플리케이션을 만들 수 있도록 지원합니다.

 

Reactive Programming이란?

reactive라는 용어는 변화에 반응하는 것을 중심을 두고 만든 프로그래밍 모델을 의미합니다.

 

데이터가 변경될 때마다 이벤트를 발생시켜서 데이터를 전달합니다.

 

데이터를 비동기적으로 처리하며 이벤트 기반 아키텍처를 통해 실시간으로 데이터의 변화에 반응할 수 있게 프로그래밍을 수행합니다.

 

https://velog.io/@effirin/R2DBC-2.-Reactive-Programming%EC%9D%B4%EB%9E%80-zh843mp2

 

주요하게 나오는 개념으로 옵저버 패턴이 있으며 Subscriber와 Publisher가 존재합니다.

 

Reactive Programming이 non-blokcing인 이유도 작업이 완료될 때까지 기다리기보다 데이터를 사용할 수 있게 되면 이벤트에 의해 반응한다는 점으로 이해할 수 있습니다.

 

Reactor

WebFlux를 활용한다고 하면 대부분의 메소드들이 Mono와 Flux를 반환하기 때문에 알아야합니다.

이 Mono와 Flux는 Reactor 라이브러리의 주요객체입니다.

Reactive 라이브러리는 Reactive Streams의 구현체로 WebFlux에서 사용하는 라이브러리입니다.

Mono와 Flux에 대해서는 다른글에서 다루어보겠습니다.

 

MVC와 WebFlux 비교

이해하기 쉬운 설명인것 같아 다른 분의 비유를 가져왔습니다.

MVC가 벽에다가 공던지고 공 받기라면 WebFlux는 공을 기차에 실어 보내고 기차가 한 바퀴 도는 순간 공을 내려주는 것이다.

 

MVC에서 만약 손이 10개라면 공을 10개 던지고 공이 돌아오는것을 기다렸다가 받고 다시 공을 던져야 할 것입니다.

WebFlux에서는 10개의 손으로 공이 돌아오는것을 기다리지 않고 20개를 기차에 실어 보내고 기차가 한 바퀴를 돌아서 20개의 공을 내려줍니다.

 

개인적으로 아래와 같이 생각했습니다.

  • 손 = Thread
  • 한 바퀴 = event

 

그런데 기차의 짐칸이 감당할 수 없을 정도로 공을 실어보내면 어떻게 될까요?

이 질문에 대한 대답은 backpressure에서 다룹니다.

 

Webflux의 등장배경

가장 큰 이유로는 자원을 효율적으로 사용할 수 있는것입니다.

하드웨어의 적은 자원으로 더 많은 작업을 수행할 수 있습니다.

 

C10K의 문제를 해결하기 위해 "만개의 클라이언트를 동시에 처리할 수 있는가?" 등장했다고도 볼 수 있습니다.

 

결국 무거운 스레드의 문제를 해결하기 위해서 등장한 것 같습니다.

OS 스레드는 생성 유지에 사용되는 메모리량이 크고 스레드가 많아질수록 콘텍스트 스위칭이 빈번하게 발생하기 때문에 보통 무한정 스레드를 생성하지 않고, 스레드풀을 만들어 재사용하는 방식으로 개발합니다.

 

이 문제를 풀기 위해서 이벤트기반의 비동기 논블록킹이 등장하게 되었습니다.

 

Webflux의 단점

  • 모든 코드가 non-blokcing 하게 동작해야 의미가 있다.
  • reactive에 대한 지식 때문에 집중하기 어려워지는 비즈니스로직
  • 쓸모없는 스택 트레이스와 힘든 디버깅

 

단순히 무거운 스레드를 해결하기 위함이라면 Webflux대신 JDK 21에 지원하는 Project Loom도 훌륭한 대안이 될 수 있습니다.

 

Webflux의 backpressure

https://engineering.linecorp.com/ko/blog/reactive-streams-with-armeria-1

 

서버가 가용할 수 있는 메모리는 한정되어 있습니다.

만약 초당 100개의 메모리를 계속 푸시한다면 버퍼는 순식간에 가득 차게 될 것이고 만약 버퍼를 다 사용해 버려서 오버플로(overflow)가 발생하면 어떻게 될까요?

 

메시지가 유실되거나, 모든 메시지를 담으려고 하다 보면 다량의 GC가 발생하기도 하고 OOM이 발생할 수도 있습니다.

https://engineering.linecorp.com/ko/blog/reactive-streams-with-armeria-1

Push 방식에서 벗어나 Pull 방식을 활용하면 Subscriber는 8개의 일을 처리하고 있다면 2개만 더 요청하여 자신이 현재 처리 가능한 범위 내에서만 메시지를 받게 할 수 있습니다.

 

 

 

 

참고자료

https://godekdls.github.io/Reactive%20Spring/springwebflux/

https://docs.spring.io/spring-framework/docs/5.0.0.M5/spring-framework-reference/html/web-reactive.html

https://engineering.linecorp.com/ko/blog/reactive-streams-with-armeria-1

https://velog.io/@effirin/R2DBC-2.-Reactive-Programming%EC%9D%B4%EB%9E%80-zh843mp2

https://pearlluck.tistory.com/726

https://gunsdevlog.blogspot.com/2020/09/reactive-streams-reactor-webflux.html

https://gunsdevlog.blogspot.com/2020/09/java-project-loom-reactive-streams.html