70DAYS) [Spring WebFlux] Project Reactor 개요 - Project Reactor

nacSeo (낙서)·2023년 1월 27일
0

◉ 학습목표

1. Reactor에 대해 알 수 있다.
2. 마블 다이어그램에 대해 알 수 있다.
3. 스케줄러에 대해 알 수 있다.
3. Operator에 대해 알 수 있다.
  1. Reactor

⦿ 학습내용

☞ Reactor

✔︎ 리액티브 스트림즈 표준 사양을 구현한 구현체 중 하나
✔︎ 완전한 Non-Blocking 통신 지원
✔︎ Mono[0|1]Flux[N]이라는 두 가지 Publisher 타입 제공
✔︎ Non-Blocking 통신을 완벽하게 지원하는 Reactor는 MSA 구조에 적합한 라이브러리
✔︎ Backpressure : Subscriber의 처리 속도가 Publisher의 emit 속도를 따라가지 못할 때 적절하게 제어하는 전략을 의미

  1. 마블 다이어그램 (Marble Diagram)

⦿ 학습내용

☞ 마블 다이어그램

✔︎ 구슬 모양의 동그라미 : 하나의 데이터를 의미, 시간의 흐름에 따라 변화하는 데이터의 흐름을 표현
✔︎ Reactor에서 제공하는 수많은 Operator의 내부 동작을 조금 더 쉽게 이해시켜줌
✔︎ 해당 Operator를 적절하게 사용하는데 도움을 줌

☞ Mono의 마블 다이어그램

✔︎ 0건 또는 1건의 데이터만 emit하는 Reactor 타입

☞ Flux의 마블 다이어그램

✔︎ 여러 개(0 ... N)의 데이터를 emit하는 Reactor 타입

  1. 스케줄러 (Scheduler)

⦿ 학습내용

☞ 스케줄러

✔︎ 쓰레드를 관리하는 관리자 역할
✔︎ Reactor Sequence 상에서 처리되는 동작들을 하나 이상의 스레드에서 동작하도록 별도의 스레드를 제공
✔︎ 복잡한 멀티 스레딩 프로세스를 단순화함
✔︎ Reactor에서는 Scheduler를 위한 별도의 Operator를 제공

☞ subscribeOn() Operator

✔︎ 데이터 소스에서 데이터를 emit하는 원본 Publisher의 실행 스레드를 지정하는 역할
✔︎ 여러 번 추가해도 하나의 스레드만 추가로 생성
✔︎ 주로 Schedulers.boundedElastic 사용

☞ publishOn() Operator

✔︎ 전달받은 데이터를 가공 처리하는 Operator 앞에 추가해서 실행 스레드를 별도로 추가하는 역할
✔︎ Operator 앞에 여러 번 추가할 경우 별도의 스레드가 추가로 생성
✔︎ 주로 Schedulers.parallel() 사용

  1. Operators

⦿ 학습내용

☞ Operator

✔︎ 종류가 다양하므로 모든 사용법 익히는 건 불가
✔︎ 상황별로 자주 사용되는 Operator를 익히고 필요한 상황마다 해당 Operator를 찾아 사용

☞ 상황별 Operator 목록 분류

✔︎ 새로운 Sequence를 생성(Creating)하고자 할 경우

  • just()
  • fromStream()
  • fromIterable()
  • fromArray()
  • range()
  • interval()
  • empty()
  • never()
  • defer()
  • using()
  • generate()
  • create()

✔︎ 기존 Sequence에서 변환 작업(Transforming)이 필요한 경우

  • map()
  • flatMap()
  • concat()
  • collectList()
  • collectMap()
  • merge()
  • zip()
  • then()
  • switchIfEmpty()
  • and()
  • when()

✔︎ Sequence 내부의 동작을 확인(Peeking)하고자 할 경우

  • doOnSubscribe()
  • doOnNext()
  • doOnError()
  • doOnCancel()
  • doFirst()
  • doOnRequest()
  • doOnTerminate()
  • doAfterTerminate()
  • doOnEach()
  • doFinally()
  • log()

✔︎ Sequence에서 데이터 필터링(Filtering)이 필요한 경우

  • filter()
  • ignoreElements()
  • distinct()
  • take()
  • next()
  • skip()
  • sample()
  • single()

✔︎ 에러를 처리(Handling errors)하고자 할 경우

  • error()
  • timeout()
  • onErrorReturn()
  • onErrorResume()
  • onErrorMap()
  • doFinally()
  • retry()

4-1. 새로운 Sequence를 생성(Creating)하고자 할 경우

⦿ 학습내용

☞ fromStream() Operator


✔︎ Java의 Stream을 입력으로 전달받아 emit하는 Operator
✔︎ reduce() : Upstream에서 emit된 두 개의 데이터를 순차적으로 누적 처리할 수 있는 Operator

☞ fromIterable() Operator


✔︎ Java의 Iterable을 입력으로 전달받아 emit하는 Operator
✔︎ List, Map, Set 등의 컬렉션을 파라미터로 전달 가능

☞ create() Operator


✔︎ 프로그래밍 방식으로 Signal 이벤트를 발생시키는 Operator
✔︎ 한 번에 여러 건의 데이터를 비동기적으로 emit할 수 있는 Operator
※ Signal : Publisher가 발생시키는 이벤트를 의미

4-2. 기존 Sequence에서 변환 작업(Transforming)이 필요한 경우

⦿ 학습내용

☞ flatMap() Operator


✔︎ 내부로 들어오는 데이터 한 건당 하나의 Sequence 생성
ex) Upstream에서 2개의 데이터 emit, 내부에서 3개의 데이터를 emit하는 Sequence
→ Downstream으로 emit되는 데이터는 총 6개 (2 x 3)
✔︎ 내부에서 정의하는 Sequence를 Inner Sequence라고 함
✔︎ 추가 스레드를 할당할 경우, 작업의 처리 순서를 보장 ❌

☞ concat() Operator


✔︎ 입력으로 전달되는 Publisher Sequence를 연결해서 차례대로 데이터를 emit
✔︎ 논리적으로 하나의 Sequence를 이어붙인 후, 시간 순서대로 데이터를 차례로 emit

☞ zip() Operator


✔︎ 입력으로 전달되는 여러 개의 Publisher Sequence에서 emit된 데이터를 결합
※ 결합 : 각 Publisher가 emit하는 데이터를 하나씩 전달받아 새로운 데이터를 만든 후 Downstream으로 전달되는 것을 의미
✔︎ Sequence에서 emit되는 데이터 중 같은 차례(index)의 데이터들이 결합
✔︎ emit되는 데이터 시점이 다를 경우, emit될 때까지 기다렸다가 결합

4-3. Sequence 내부의 동작을 확인(Peeking)하고자 할 경우

⦿ 학습내용

☞ doOnNext() Operator


✔︎ 데이터 emit 시 트리거되어 부수 효과(side-effect)를 추가할 수 있는 Operator
※ 부수 효과(side-effect) : 어떤 동작을 실행하되 리턴 값이 없는 것을 의미

☞ log() Operator


✔︎ Publisher에서 발생하는 Signal 이벤트를 로그로 출력해주는 역할
✔︎ 구독 시점에 onSubscribe Signal 이벤트 발생
✔︎ 데이터 요청 시, request Signal 이벤트 발생
✔︎ Publisher가 데이터를 emit할 때, onNext Signal 이벤트 발생
✔︎ Publisher의 데이터 emit이 정상적으로 종료되면 onComplete Signal 이벤트 발생

4-4. 에러를 처리(Handling errors)하고자 할 경우

⦿ 학습내용

☞ error() Operator


✔︎ 의도적으로 onError Signal 이벤트를 발생시킬 때 사용하는 Operator

☞ timeout() Operator


✔︎ 입력으로 주어진 시간동안 emit되는 데이터가 없으면 onError Signal 이벤트 발생

☞ retry() Operator


✔︎ Sequence 상 에러가 발생할 경우, 입력으로 주어진 숫자만큼 재구독해서 Sequence 다시 시작

timeout() Operator와 retry() Operator는 함께 사용하는 경우 多❗️

◉ 느낀 점

☞ 어제 배운 리액티브 스트림즈의 구현체 중 하나인 Project Reactor에 대해 학습하는 시간이었다. 새로운 프로그래밍 기술을 접하며 낯설고 어렵기도 하지만, 경쟁력을 높일 수 있는 현대적인 기술이기에 흥미를 가지고 열심히 ^^,,
마지막에 리액티브 프로그래밍의 핵심인 Operator들에 대해 알아보면서 머리가 터질뻔 했지만 ^^,, 한 번에 다 공부하는 것이 아니라 상황에 맞게 필요할 때 찾아 사용하면 된다기에 실제 많이 사용되는 Operator들에 대해 알아보면서 사용법에 포커싱을 맞춰 학습했다. 주말 간 잘 정리해서 머릿 속에 넣어야겠다. 🤯

◉ 내일의 키워드

・ Spring WebFlux
・ Spring Data R2DBC
profile
백엔드 개발자 김창하입니다 🙇‍♂️

0개의 댓글