1. Reactor에 대해 알 수 있다.
2. 마블 다이어그램에 대해 알 수 있다.
3. 스케줄러에 대해 알 수 있다.
3. Operator에 대해 알 수 있다.
- Reactor
✔︎ 리액티브 스트림즈 표준 사양을 구현한 구현체 중 하나
✔︎ 완전한 Non-Blocking
통신 지원
✔︎ Mono[0|1]와 Flux[N]이라는 두 가지 Publisher 타입 제공
✔︎ Non-Blocking 통신을 완벽하게 지원하는 Reactor는 MSA 구조에 적합한 라이브러리
✔︎ Backpressure : Subscriber의 처리 속도가 Publisher의 emit 속도를 따라가지 못할 때 적절하게 제어하는 전략을 의미
- 마블 다이어그램 (Marble Diagram)
✔︎ 구슬 모양의 동그라미 : 하나의 데이터를 의미, 시간의 흐름에 따라 변화하는 데이터의 흐름을 표현
✔︎ Reactor에서 제공하는 수많은 Operator의 내부 동작을 조금 더 쉽게 이해시켜줌
✔︎ 해당 Operator를 적절하게 사용하는데 도움을 줌
✔︎ 0건 또는 1건의 데이터만 emit하는 Reactor 타입
✔︎ 여러 개(0 ... N)의 데이터를 emit하는 Reactor 타입
- 스케줄러 (Scheduler)
✔︎ 쓰레드를 관리하는 관리자 역할
✔︎ Reactor Sequence 상에서 처리되는 동작들을 하나 이상의 스레드에서 동작하도록 별도의 스레드를 제공
✔︎ 복잡한 멀티 스레딩 프로세스를 단순화함
✔︎ Reactor에서는 Scheduler를 위한 별도의 Operator를 제공
✔︎ 데이터 소스에서 데이터를 emit하는 원본 Publisher의 실행 스레드를 지정하는 역할
✔︎ 여러 번 추가해도 하나의 스레드만 추가로 생성
✔︎ 주로 Schedulers.boundedElastic
사용
✔︎ 전달받은 데이터를 가공 처리하는 Operator 앞에 추가해서 실행 스레드를 별도로 추가하는 역할
✔︎ Operator 앞에 여러 번 추가할 경우 별도의 스레드가 추가로 생성
✔︎ 주로 Schedulers.parallel()
사용
- Operators
✔︎ 종류가 다양하므로 모든 사용법 익히는 건 불가
✔︎ 상황별로 자주 사용되는 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)하고자 할 경우
✔︎ Java의 Stream을 입력으로 전달받아 emit하는 Operator
✔︎ reduce()
: Upstream에서 emit된 두 개의 데이터를 순차적으로 누적 처리할 수 있는 Operator
✔︎ Java의 Iterable을 입력으로 전달받아 emit하는 Operator
✔︎ List, Map, Set 등의 컬렉션을 파라미터로 전달 가능
✔︎ 프로그래밍 방식으로 Signal 이벤트를 발생시키는 Operator
✔︎ 한 번에 여러 건의 데이터를 비동기적으로 emit할 수 있는 Operator
※ Signal : Publisher가 발생시키는 이벤트를 의미
4-2. 기존 Sequence에서 변환 작업(Transforming)이 필요한 경우
✔︎ 내부로 들어오는 데이터 한 건당 하나의 Sequence 생성
ex) Upstream에서 2개의 데이터 emit, 내부에서 3개의 데이터를 emit하는 Sequence
→ Downstream으로 emit되는 데이터는 총 6개 (2 x 3)
✔︎ 내부에서 정의하는 Sequence를 Inner Sequence라고 함
✔︎ 추가 스레드를 할당할 경우, 작업의 처리 순서를 보장 ❌
✔︎ 입력으로 전달되는 Publisher Sequence를 연결해서 차례대로 데이터를 emit
✔︎ 논리적으로 하나의 Sequence를 이어붙인 후, 시간 순서대로 데이터를 차례로 emit
✔︎ 입력으로 전달되는 여러 개의 Publisher Sequence에서 emit된 데이터를 결합
※ 결합 : 각 Publisher가 emit하는 데이터를 하나씩 전달받아 새로운 데이터를 만든 후 Downstream으로 전달되는 것을 의미
✔︎ Sequence에서 emit되는 데이터 중 같은 차례(index)의 데이터들이 결합
✔︎ emit되는 데이터 시점이 다를 경우, emit될 때까지 기다렸다가 결합
4-3. Sequence 내부의 동작을 확인(Peeking)하고자 할 경우
✔︎ 데이터 emit 시 트리거되어 부수 효과(side-effect)를 추가할 수 있는 Operator
※ 부수 효과(side-effect) : 어떤 동작을 실행하되 리턴 값이 없는 것을 의미
✔︎ Publisher에서 발생하는 Signal 이벤트를 로그로 출력해주는 역할
✔︎ 구독 시점에 onSubscribe Signal
이벤트 발생
✔︎ 데이터 요청 시, request Signal
이벤트 발생
✔︎ Publisher가 데이터를 emit할 때, onNext Signal
이벤트 발생
✔︎ Publisher의 데이터 emit이 정상적으로 종료되면 onComplete Signal
이벤트 발생
4-4. 에러를 처리(Handling errors)하고자 할 경우
✔︎ 의도적으로 onError Signal 이벤트를 발생시킬 때 사용하는 Operator
✔︎ 입력으로 주어진 시간동안 emit되는 데이터가 없으면 onError Signal 이벤트 발생
✔︎ Sequence 상 에러가 발생할 경우, 입력으로 주어진 숫자만큼 재구독해서 Sequence 다시 시작
※ timeout()
Operator와 retry()
Operator는 함께 사용하는 경우 多❗️
☞ 어제 배운 리액티브 스트림즈의 구현체 중 하나인 Project Reactor에 대해 학습하는 시간이었다. 새로운 프로그래밍 기술을 접하며 낯설고 어렵기도 하지만, 경쟁력을 높일 수 있는 현대적인 기술이기에 흥미를 가지고 열심히 ^^,,
마지막에 리액티브 프로그래밍의 핵심인 Operator들에 대해 알아보면서 머리가 터질뻔 했지만 ^^,, 한 번에 다 공부하는 것이 아니라 상황에 맞게 필요할 때 찾아 사용하면 된다기에 실제 많이 사용되는 Operator들에 대해 알아보면서 사용법에 포커싱을 맞춰 학습했다. 주말 간 잘 정리해서 머릿 속에 넣어야겠다. 🤯
・ Spring WebFlux
・ Spring Data R2DBC