[스프링 웹플럭스] 1.1.2. 리액티브란 무엇이며 왜?

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

논-블럭킹과 펑셔널에 대해 언급했는데 왜 리액티브를 해야 하며 그게 무슨 의미가 있을까?

“리액티브”라는 단어는 I/O 이벤트에 반응하는 네트워크 컴포넌트, 마우스 이벤트에 반응하는 UI 컨트롤러 등 어떤 변화에 반응하는 것을 아우르는 프로그래밍 모델을 뜻한다. 그런 점에서 논-블럭킹은 반응형이다 왜냐면 블럭킹되지 않고 작업이 완료되거나 데이터가 전달되는 등의 알림에 반응하는 모델 속에 있기 떄문이다.

우리가 스프링 팀에서 “리액티브”와 더불어 중요하게 여기는 매커니즘 하나가 바로 논-블럭킹 백 프레셔(back pressure)다. 동기적이고, 순차적인 코드, 블럭킹 콜은 자연적으로 백 프레셔를 제공한다. 왜냐면 호출한 쪽이 그 작업이 끝날 때까지 기다려야 하니까. 하지만 논-블럭킹 코드에서는 이벤트를 공금하는 쪽(publisher)이 지나치게 빨라서 그걸 소비하는 쪽이 뻗지 않게 이벤트 비율을 조절하는것이 중요해진다.

리액티브 스트림은 작은 규모의 스팩이고 자바 9가 채용했다. 플로우 API로 비동기적인 컴포넌트간의 백 프레셔를 고려한 상호 교류를 정의했다. 예를 들어, 데이터 저장소는 발행자처럼 동작하며 데이터를 공급할 수 있다. 그리고 그 데이터를 구독자처럼 동작하는 HTTP server가 받아서 응답을 작성할 수 있다. 리액티브 스트림의 주요 목적은 구독자로 하여금 얼마나 빨리 또는 느리게 공급자가 데이터를 생성해야 하는지 제어할 수 있게끔 하는 것이다.

자주받는 질문: 발행자를 늦출 수 없으면?
리액티브 스트림의 목적인 오로지 그러한 매커니즘과 경계를 만들는 것 뿐이다. 만약에 발행자를 늦출 수 없다면 버퍼에 담을지, 버릴지, 실패할지 정해야 한다.

[스프링 웹플럭스] 1.1.4. 프로그래밍 모델

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

spring-web  모듈은 스프링 웹플러스가 올라가는 리액티브 기반 시설을 포함하고 있다. HTTP 추상화, 리액티브 스트림 서버 어댑터, 리액티브 코덱과 핵심 웹 API가 있다. 웹 API는 서블릿 API와 비슷하자먼 논-블럭킹용이다.

그 기반 시설 위에서 스프링 웹플럭스는 두가지 프로그래밍 모델을 제공한다.

  • 애노테이션 컨트롤러 – 스프링 MVC와 동일하며 spring-web 모듈에서 제공하는 것과 동일한 애노테이션에 기반하고 있다. 스프링 MVC와 웹플럭스 컨트롤러 모두 리액티브 (Reactor, RxJava) 리턴 타이을 지원하기 때문에 따로 분리해서 말하긴 어렵다. 주목할만한 차이라면 웹플러그는 리액티브 @RequestBody 인자로 지원한다.
  • 함수형 Endpoint – 람다 기반의 가벼운 함수형 프로그래밍 모델이다. 애플리케이션이 요청을 라우팅하고 처리 할 때 사용할 수 있는 작은 라이브러리나 유틸리티 셋으로 생각할 수 있다. 애노테이션 컨트롤러와의 큰 차이점은 애플리케이션이 요청 처리의 처음부터 끝까지 책임진다는 점이다. 애노테이션 컨트롤러에서는 애노테이션으로 인텐트를 표현하고 컨트롤러의 코드는 프레임워크에서 나중에 호출(콜 백)되는 식이었던과 비교할 수 있다.

 

[스프링 웹플럭스] 1.1.3. 리액티브 API

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

리액티브 스트림은 상호 호환성에 있어서 중요한 역할을 한다. 라이브러리나 기반 컴포넌트로써 중요한 역할을 하지만 애플리케이션 API로써는 유용하지 않다 왜냐면 상당히 로우 레벨이기 때문이다. 애플리케이션이 필요로 하는것은 보다 상위 레벨의 풍부하며 비동기 로직을 조합하는데 사용할 함수 API 같은 것이다. 자바 8의Stream API와 비슷하지만 컬렉션에 국한되진 않은 것이 필요하다. 바로 그러한 역할을 리액티브 라이브러리가 할 것이다.

스프링 웹플럭스에서 선택 리액티브 라이브러리는 리액터다. 리액터는 리액티브엑스의 다양한 오퍼레이터에 해당하는 풍부한 기능 셋을 통해 0..1과 0..N 개의 데이터 시퀀스를 다룰 수 있는 MonoFlux API 타입을 제공한다. 리액터는 리액티브 스트림 라이브러리의 일종이며 따라서 그 모든 오퍼레이터는 논-블럭킹 백 프레셔를 지원한다. 리액터는 서버 사이드 자바에 집중하고 있다. 스프링과 긴밀하게 협업하며 개발되었다.

웹플럭스는 리액터를 핵심 의존성으로 필요로 하지만 다른 리액티브 스트림 라이브러리로 교체할 수 있다. 일반적으로 웹플럭스 API는 평범한  Publisher를 입력값으로 받고 내부적으로 리액터 타입으로 변환하여 사용하고 Flux 나 Mono 를 결과값으로 반환한다. 따라서 여러분은 어떠한 Publisher라도 입력값으로 전달할 수 있으며 결과값에 오퍼레이션을 적용할 수 있다. 하지만 다른 라이브러리를 사용한다면 결과값을 다른 리액티브 라이브러로 변환해야 할 것이다. 가능한한 애노테이션을 사용한 컨테이너처럼, 웹플럭스는 투명하게 RxJava나 다른 리액티브 라이브러리를 사용할 수 있다. 자게한 내용은 리액티브 라이브러리를 참고하라.

[스프링 웹플럭스] 1.1.1 왜 새로운 웹 프레임워크인가?

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

적은 수의 쓰레드로 동시성(concurrency)을 처리하고 더 적은 하드웨어 리소스로도 확장성(scale)을 꽤할 수 있는 논-블럭킹 웹 스택이 필요하다. 서블릿 3.1은 논-블럭킹 I/O API를 제공했다. 하지만 그것을 사용하면 동기적이거나 (Filter, Servlet) 블럭킹적인(getParameter, getPart) 서블릿 API와는 멀어진다. 이것이 다양한 논-블럭킹 런타임을 아우르는 새로운 공통 API를 만들게된 주요한 동기다. 이점은 네티 같은 서버는 매우 잘 만들어진 비동기, 논-블럭킹 영역이 있었기 때문에 중요했다.

반면 또 다른 답변으로는 펑셔널 프로그래밍을 들 수 있다. 이것은 마치 자바 5에서 애노테이션을 추가해 애노테이션을 붙인 REST 컨트롤러나 단위 테스트 같은 기회를 만들어낸 것처럼, 자바 8에서 람다 표현식으로 자바에 펑셔널 API라는 가능성을 만들어낸 것이다. 이는 논-블럭킹 애플리케이션과 컨티뉴에이션 스타일 API의 친구 격이다. CPS (Continuation-passing style)는 비동기 적인 로직을 선언적으로 조합할 수 있게 해주는 CompletableFuture와 ReactiveX로 인해 유명해졌다. 자바 8 프로그래밍 모델은 스프링 웹플러스가 펑셔널 웹 엔드포인트를 애노테이션 기반 컨트롤러와 함께 제공할 수 있게 해준다.

[스프링 웹플럭스] 1.1 소개

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

1.1 소개

기존의 스프링 웹 MVC는 서블릿 API와 서블릿 컨테이너 기반으로 작성했지만 리액티브 스택의 웹 프레임워크에 해당하는 스프링 웹플럭스는 버전 5 후반에 추가했다. 완전히 논-블럭킹이며 리액티브 스트림의 백 프레셔를 지원하고 네티, 언더토우 그리고 서블릿 3.1+ 컨테이너에서 사용할 수 있다.

두 소스 모델은 spring-webmvc와 spring-webflux에 동시에 나란히 스프링 프레임워크안에 존재한다. 각 모듈은 필수가 아니다. 애플리케이션은 둘 중 하나를 사용하거나, 혹은 둘 다 사용할 수도 있다. 가령, 스프링 MVC 컨트롤러를 리액티브 WebClient랑 같이 사용할 수 있다.

웹 프레임워크에 더해 스프링 웹플러스는 HTTP 요청을 수행할  WebClient를 제공한다. 웹 엔드포인트 테스팅 용으로 WebTestClient도 제공하며 웹소켓용 리액티브 클라이언트와 서버도 제공한다.