R2DBC를 사용한다고 하면, 자주 같이 쓰이는 기술이 Webflux다.
Webflux는 무엇이며, 어떤 이유로 Webflux + R2DBC 조합을 같이 쓰는 것일까?
우선 비교적 자주 쓰이는 SpringMVC와 비교하며 Spring Webflux를 이해해보자.
Spring MVC 공식문서에 따르면, Spring Webflux 대부분의 구조 및 설정은 Spring MVC와 동일하다고 명시되어 있다.
그러나 동시성 모델과 블로킹/쓰레드 기본 전략이 다르다.
MVC에서는 애플리케이션이 스레드를 차단(blocking)할 수 있다는 가정 하에 큰 스레드풀을 가지고 있고,
WebFlux에서는 스레드가 차단되지 않아(non-blocking) 적은 스레드풀을 사용하여 request들을 처리한다는 점이다.
명령형 프로그래밍은 작성하기도, 이해하기도, 디버깅하기도 쉽다. 지금까지 대부분 블로킹 방식을 사용했기 때문에, 사용할 수 있는 라이브러리가 가장 풍부하다.
다른 웹 스택과 같은 실행 환경을 제공하면서도, 다양한 서버(Netty, Tomcat, Jetty, Undertow 등)와 여러 리액티브 라이브러리(리액터, JxJava 등)를 지원하며, 두 가지 프로그래밍 모델(어노테이션을 선언한 컨트롤러와 엔드포인트)를 사용할 수 있다.
Spring MVC냐 Spring Webflux냐
두 프레임워크를 대척점에 두고 이분법적으로 보는 것은 좋지 않지만, 둘의 특성을 이해하기 위해서 어떤 경우에 어떤 프레임워크를 쓰는 것이 추천되는지 살펴보자.
'마이크로 서비스 아키텍처' → 두 프레임워크 조합 가능
마이크로 아키텍처에선 Spring MVC로 만든 어플리케이션과, Spring Webflux 컨트롤러나 함수형 엔드포인트를 사용한 어플리케이션을 조합할 수 있다. 두 프레임워크 모두 어노테이션 기반 프로그래밍 모델을 지원하기 때문에 각자 맞는 툴을 선택할 수 있다.
블로킹 방식의 JPA, JDBC를 쓰고 있을 경우 → Spring MVC
블로킹 방식의 persistence API (JPA, JDBC)나 네트워크 API를 사용하고 있다면 Spring MVC가 최소한 아키텍처를 통일할 수 있으므로 가장 좋은 정책이다. (리액터나 RxJava로도 각 쓰레드에서 블로킹 API를 호출할 수 있지만, 이렇게 하면 논블로킹 웹 스택을 거의 활용하기 어렵다.)
Java 8 람다 또는 Kotlin으로 개발할 수 있는 경량의 함수형 웹 프레임워크를 찾는 경우 → Spring Webflux의 함수형 웹 엔드 포인트 사용
로직을 투명하게 제어할 수 있기 때문에 요구사항이 덜 복잡한 소규모 어플리케이션이나 마이크로서비스에서도 좋은 선택
비동기, non-blocking 리액티브 서비스 + 마이크로서비스 아키텍처 + Spring → Spring Webflux
비동기, non-blocking 리액티브 서비스를 만들고자 할 때, 특히 서비스 간의 호출이 잦은 마이크로서비스 아키텍처인 상황에서 다른 프레임워크가 아닌 Spring을 계속해서 사용하고 싶다면 Spring Webflux의 도입을 추천.
스프링 프레임워크 버전 5(Spring 5)는 리액티프 프로그래밍을 위한 WebFlux를 2017년 8월에 릴리즈했고, 2019년 12월에 리액티브 드라이브를 사용한 관계형 데이터베이스인 R2DBC를 릴리즈하였다.
이후 Webflux + R2DBC 조합이 등장하는데... 많은 조합 중에 왜 이 조합인가?
결론부터 말하자면, R2DBC + Webflux가 높은 동시성때는 좋은 선택이기 때문이다.
- 요청당 CPU를 조금 사용함
- 용청당 메모리가 조금 필요함
- 응답시간이 빠름
- 처리량도 높아짐
- JAR도 가벼워짐
위 내용은 스프링 blocking vs non-blocking : R2DBC vs JDBC & WebFlux vs Web MVC 에서 발췌한 내용인데, 해당 포스트에선 blocking과 non-blocking을 중심으로 각 기술들의 조합을 비교하고 있다. 비교군은 Web MVC / WebFlux 그리고 JDBC / R2DBC로, 총 4가지 조합을 비교했다.
실험 결과(응답 시간 / 처리량 / CPU 사용량 / 메모리 사용량)를 통해 얻은 결론을 각 비교군 별로 요약하면 다음과 같다.
▷ 다시 한번 정리하자면,
높은 동시성에선 Spring WebFlux + R2DBC
낮은 동시성에선 Spring MVC + JDBC
조합이 적합하다.
따라서 Spring WebFlux + R2DBC
조합은...
1. 높은 동시성 처리
R2DBC는 적은 스레드로 동시성을 처리하고 더 적은 하드웨어 리소스로 확장할 수 있고, WebFlux에서는 스레드가 차단되지 않아(non-blocking) 적은 스레드풀을 사용하여 request들을 처리하므로, 높은 동시성 처리에 적합하다.
2. 리액티브 프로그래밍
R2DBC는 리액티브 프로그래밍을 지원하는 데이터베이스 접근 API이며, WebFlux는 다른 웹 스택과 같은 실행 환경을 제공하면서도, 여러 리액티브 라이브러리(리액터, JxJava 등)를 지원한다는 점에서, 리액티브 프로그래밍에도 적합하다.
라고 내 맘대로(뇌피셜) 정리할 수 있겠다.
[출처]
Spring WebFlux (1)
Spring5 리액티브 (Web flux)
스프링 blocking vs non-blocking : R2DBC vs JDBC & WebFlux vs Web MVC