https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux-programming-models

스프링 MVC를 써야 하나 웹플럭스를 써야 하나? 차이점을 살펴보자.

이미 동작하는 스프링 MVC 애프리케이션이 있다면 그대로도 괜찮다. 바꿀 필요는 없다. 절차적인 프로그래밍은 가장 쉽게 작성하고, 이해하며 디버깅할 수 있는 코드다. 역사적으로 대부분이 블럭킹인 수많은 라이브러리를 선택해 사용할 수 있다.

논-블럭킹 웹 스택을 이미 살펴보고 있다면, 스프링 웹플럭스는 그 영역에서 다른 것들과 동일한 실행 모델을 제공하며 서버를 선택해 사용할 수 있게끔 해준다. 네티, 톰캣, 제티, 언더토우, 서블릿 3.1+ 컨테이너를 사용할 수 있다. 프로그래밍 모델로는 애노테이션 컨트롤러와 펑셔널 웹 엔드포인트 그리고 리액터, RxJava 등의 리액티브 라이브러리를 선택해 사용할 수 있다.

가벼운 펑셔널 웹 프레임워크를 자바 8 람다나 코틀린으로 사용하고 싶다면 스프링 웹 플럭스 펑셔널 웹 엔드포인트를 사용할 수 있다. 작은 애플리케이션이나 복잡도가 낮은 마이크로서비스용으로 사용하여 투명성과 제어에 대한 장점을 살릴 수 있다.

마이크로서비스 아키텍처 안에서 스프링 MVC 애플리케이션과 스프링 웹플럭스 컨트롤러 또는 스프링 웹플럭스 펑셔널 엔드포인트를 혼용할 수 있다. 똑같은 애노테이션 기반의 프로그래밍 모델을 양쪽 프레임워크 모두에 사용함으로써 기존 지식의 재사용을 편하게 하며 적절한 곳에 적절한 툴을 선택해 사용하게 해준다.

애플리케이션을 평가하는 쉬운 방법중 하나는 의존성을 확인하는 것이다. 만약에 블록킹 영속화 API (JPA, JDBC)를 사용하거나 네트워크 API를 사용한다면 스프링 MVC가 가장 흔한 아키텍처로는 최적이다. 기술적으로는 리액터나 RxJava로도 블럭킹 호출을 별도의 쓰레드로 처리하는게 가능하지만 대부분의 논-블럭킹 웹 스택에서는 그런 쓰레드를 만들지 않는다.

리모트 서비스를 호출하는 스프링 MVC 애플리케이션이 있다면 리액티브 WebClient를 사용해보자. 스프링 MVC 애플리케이션 메서드에서 리액티브 타입 (리액터, RxJava, 그리고 다른 것)을 직접 반환할 수 있다. 호출 당 지연이 크거나 상호 의존도가 클 수록 효과를 크게 볼 수 있다. 스프링 MVC 컨트롤러는 다른 리액티브 컴포넌트를 호출할 수 도 있다.

대규모 팀이라면 논-블럭킹과 선언적인 프로그래밍으로 옮기는데 드는 학습 비용을 염두해야 한다. 실용적인 방법은 전체를 전화하는게 아니라 리액티브 WebClient를 사용하는것 부터 시작하는 것이다. 조금씩 바꾸기 시작한 다음 그 효과를 측정하라. 애플리케이션 전체를 다 바꿀 필욘 없을 것으로 예상한다.

어떤 장점을 얻을 수 있는지 확실하지 않다면, 논-블럭킹 I/O의 동작 방법(단일 쓰레드 Node.js의 동시성은 모순이 아니다.)과 그 효과에 대해 학습하라. 주목할 점은 "하드웨어는 조금 쓰면서 확장하는 것"이지만 느리거나 예측 불가능한 어느정도의 네트워크 I/O 없이는 그 효과를 보장하진 않는다. 넷플릭스의 이 블로그가 참고하기 좋다.