Spring/스프링으로 시작하는 리액티브 프로그래밍

[Java] Reactor 간단 정리

꾸준함. 2024. 7. 14. 23:58

Reactor

  • Spring Framework 팀의 주도하에 개발된 리액티브 스트림즈의 구현체
  • Spring Framework 5 버전부터 리액티브 스택에 포함되어 Spring WebFlux 기반의 리액티브 애플리케이션을 제작하기 위한 핵심 역할 담당
  • 간단하게 요약하면 리액티브 스트림즈의 구현체인 Reactor는 리액티브 프로그래밍을 위한 라이브러리

 

1. Reactor의 주요 특징

  • Reactive Streams: 앞서 언급했다시피 Reactor는 리액티브 스트림즈 사양을 구현한 리액티브 라이브러리
  • Non-Blocking: Reactor는 JVM 위에 실행되는 non-blocking 애플리케이션을 제작하기 위해 필요한 핵심 기술
  • Java's Functional API: Reactor에서 Publisher와 Subscriber 간의 상호작용은 자바의 함수형 프로그래밍 API를 통해 이루어짐
  • Flux [N]: Reactor의 Publisher 타입 중 하나로 0개부터 N개 즉 무한대의 데이터를 내보낼 수 있는 Reactor의 Publisher
  • Mono [0|1]: Reactor에서 지원하는 Publisher 타입 중 하나로 데이터를 0개 혹은 1개 내보내는 것에 특화된 Publisher
  • Well-suited for Microservices: non-blocking I/O 특징을 가지는 Reactor는 마이크로 서비스 기반 시스템에서 수많은 서비스들 간에 지속적으로 발생하는 I/O를 처리하기에 적합한 기술
  • Backpressure-ready Network: Reactor는 Publisher로부터 전달받은 데이터를 처리하는 데 있어 과부하가 걸리지 않도록 제어하는 Backpressure를 지원
    • Backpressure는 Publisher로부터 전달되는 대량의 데이터를 Subscriber가 적절하게 처리하기 위한 방법

 

https://projectreactor.io/

 

2. Reactor의 구성요소

 

2.1 Publisher

  • Reactor의 기본 구성 요소로 데이터를 생성하고 Subscriber에게 전송하는 역할 수행
  • Reactor의 모든 데이터 흐름은 Publisher로부터 시작

 

2.2 Flux

  • 0개 이상의 아이템을 비동기적으로 제공하는 Publisher
  • 여러 개의 아이템을 처리해야 하는 경우 주로 사용
  • ex) R2DBC에서 여러 레코드를 가져올 때 사용

 

Flux<String> flux = Flux.just("item1", "item2", "item3");

 

2.3 Mono

  • 최대 1개의 아이템을 비동기적으로 제공하는 Publisher
  • 하나의 아이템을 처리하거나 처리할 아이템이 없을 경우 사용
  • ex) 특정 조건에 맞는 하나의 레코드를 가져올 때 사용

 

Mono<String> mono = Mono.just("singleItem");

 

2.4 Subscriber

  • Publisher에서 제공하는 데이터를 소비하는 구성 요소
  • 네 가지 메서드를 가지고 있음
    • onSubscribe: Publisher 구독이 시작될 떄 호출
    • onNext: Publisher가 제공하는 데이터를 받을 때마다 호출
    • onError: 데이터 처리 중 오류가 발생했을 때 호출
    • onComplete: 데이터 스트림이 모두 전송되었을 때 호출

 

2.5 Subscription

  • Publisher와 Subscriber 간의 관계를 나타냄
  • Subscriber는 Subscription을 통해 데이터 요청량 제어

 

2.6 Processor

  • Publisher와 Subscriber의 역할을 동시에 수행하는 구성 요소
  • 데이터 스트림을 중간에서 처리하고 변환할 때 유용

 

2.7 Scheduler

  • Reactor에서 비동기 실행을 제어하는 구성 요소
  • 쓰레드 풀을 관리하고 작업을 특정 쓰레드나 쓰레드 풀에서 실행할 수 있도록 지원
  • Reactor는 다양한 스케줄러를 제공
    • Schedulers.parallel(): 고정된 크기의 쓰레드 풀을 사용하는 스케줄러
    • Schedulers.elastic(): 동적으로 크기를 조정하는 쓰레드 풀을 사용하는 스케줄러
    • Schedulers.single(): 단일 쓰레드를 사용하는 스케줄러

 

2.8 Operators

  • Reactor는 다양한 연산자를 제공하여 데이터를 변환, 필터링, 결합 및 집계할 수 있도록 지원
  • 주요 연산자는 다음과 같음
    • map: 데이터를 다른 형태로 변환
    • flatMap: 비동기 작업을 실행하고 결과를 단일 스트림으로 결합
    • filter: 특정 조건을 만족하는 데이터만 통과시킴

 

Flux<Integer> numbers = Flux.just(1, 2, 3);
Flux<Integer> squared = numbers.map(n -> n * n);

Flux<String> ids = Flux.just("id1", "id2");
Flux<User> users = ids.flatMap(id -> userService.findUserById(id));

Flux<Integer> evenNumbers = numbers.filter(n -> n % 2 == 0);

 

참고

  • 스프링으로 시작하는 리액티브 프로그래밍 (황정식 저자)
반응형