IT/Spring WebFlux

Project Reactor

밝은내일 2020. 12. 13. 19:38

Overview

Project Reactor란 리엑티브 프로그래밍을 구현한 라이브러리입니다. Reactor는 Reactive Streams를 기반으로 JVM에서 리액티브 프로그래밍을 가능하게 합니다. 스프링 5에서 추가된 Spring Webflux는 내부적으로 Project Reactor를 reactive library로 사용합니다. Reactor는 Reactive Streams의 구현체이기 때문에 자연스럽게 Non-Blocking, Back Pressure을 지원합니다.

The Assembly Line Analogy

리액티브 애플리케이션으로 처리되는 데이터는 마치 공정 라인을 따라 이동하는것 처럼 보입니다. 리액터는 컨베이너 벨트이자 워크 스태이션입니다. 원료가 되는 가공되지 않은 물질들이 들어오고 막바지에는 소비자에게 발송될 하나의 상품이됩니다.

이 가공되지 않은 물질들은 다양한 형태로 지나가고 다른 중간 스텝 또는 보다 큰 공정 라인에 일부로 들어가서 하나의 중간 조각들이 될 수 있습니다. 특정 지점에 작업의 밀림이나 막힘이 있다면, 그 지점 때문에 고통받는 워크스테이션은 작업량의 제한을 upstream에 요청할 수 있습니다.

Features

리액터와 같은 리액티브 라이브러리는 고전적인 비동기 접근법의 결점을 극복하고 아래와 같은 추가적인 특징을 가지고 있습니다.

  • Composability
  • A rich vocabulary of operator
  • Nothing happens until you subscribe

Composability

Composability는 다수의 비동기 task를 조율하는 능력을 말합니다. 이전 tasks의 결과들로 다음 tasks의 입력으로 사용할 수 있습니다. 또 몇 가지 tasks는 fork-join 스타일로 수행이 가능합니다. 게다가 작업이 완료된 비동기 태스크를 분리된 컴포넌트로 재사용이 가능합니다. 

Tasks를 조율하는 능력은 사실 코드의 가독성(Readability)과 유지보수성(Maintainability)과 강하게 결합되어 있습니다. 비동기 프로세스의 수와 복잡성이 커질 수록 코드를 만들고 읽는 것은 매우 어려워집니다. Callback 모델은 심플하지만, 결정전인 단점은 바로 Callback 지옥입니다. (실행된 callback으로 부터 새로운 callback이 있고, 이 새로운 callback으로부터 다른 새로운 callback이 반복되는 ...)

다행스럽게도 리액터는 풍부한 구성 옵션을 제공합니다. 모든것은 보통 같은 레벨을 유지합니다 즉 Callback 지옥과 같은 nesting을 최소화 합니다.

Rich Operators

리액터에서 연산자(operators)들은 조립 공정 라인에서 워크스테이션입니다. 각 연산자 Publisher에 행동을 추가하고 Publisher의 이전 스텝에 새로운 인스턴스에 추가하여 감쌉니다. 첫 번째 Publisher로 부터 온 데이터는 이런식으로 전체 체인으로 연결됩니다. 그리고 데이터는 체인을 따라 바뀌어가면서 아래로 내려갑니다. 마침내 한 subscriber가 프로세스를 끝냅니다. 

리액티브 스트림 스펙상에서는 연산자들을 전혀 명세하지 않았지만, 리액터와 같은 리액티브 라이브러리의 가장 최고의 가치는 그들이 제공하는 풍부한 연산자들입니다. 연산자들은 간단한 변형, 복잡한 오케스트레이션의 필터링 그리고 에러 핸들링과 같은 대부분의 영역을 커버합니다.

Nothing Happens Until Yousubscribe

리액터에서 기본적으로 Publisher의 체인만으로는 아무것도 동작하지 않습니다. Subscribing 동작을 통해 Publisher와 Subscriber를 묶고 Publisher 전체 체인으로 데이터를 흐르게 만듭니다. 이런 과정은 upstream으로 전파된 Subscriber로 부터 온 단일 요청 신호에 의해서 내부적으로 실행됩니다.

Hot vs Cold Sequence

일련의 데이터를 순차적으로 발행하는 Publisher를 Reactive Sequence라고도 부릅니다. 이러한 Sequence는 크게 두 가지 카테고리인 Hot Sequence 와 Cold Sequence가 있습니다. 둘의 차이는 Subscribers에 대해 Sequence가 어떻게 대응하는지에 달려있습니다.

Cold Sequence - 각 Subscriber 마다 Cold Sequence는 새로 시작합니다. 이때 원본 데이터도 포함합니다. 예를 들어, 일련의 데이터가 HTTP 호출을 하는 데이터라면, 각 Subscriber에서 독립적인 새로운 HTTP 요청을 만들게 됩니다.

Hot Sequence - 각 Subscriber 마다 Hot Sequence는 처음부터 새로 시작하지 않습니다. 그것보다는, Subscriber들이 Sequnce를 구독한 뒤에 Sequence가 방출하는 시그널을 받습니다. 주의할 점으로는 몇 가지 Hot Sequence들은 완전히 또는 부분적으로 방출한 시그널 기록을 캐시하거나 재동작 시킬 수 있습니다. 또 Hot Sequence는 Subscriber가 듣고 있지 않아도 시그널을 방출할 수 있습니다. (사실 이는 Nothing Happens Until Yousubscribe 규칙에서 예외적인 경우입니다)

References

projectreactor.io/docs/core/release/reference/

반응형

'IT > Spring WebFlux' 카테고리의 다른 글

Create, Subscribe, Disposable  (0) 2020.12.21
Reactor Core - Mono & Flux  (0) 2020.12.14
Event-Driven & WebFlux  (1) 2020.11.10
Back Pressure  (0) 2020.11.07
Non-Blocking  (0) 2020.11.07