Principal

리액티브 프로그래밍(Reactive Programming)이 뭐냐고?

팅리엔 2022. 3. 16. 17:47

리액티브 프로그래밍

지금까지 흔히 사용했던 리스트(List)와 같은 컬렉션은 이미 데이터가 '생성'되어 있습니다.
하지만 리액티브 프로그래밍에서는 '데이터가 통지될 때마다' 프로그램이 '반응'하여 데이터를 처리합니다.
이러한 데이터의 흐름을 데이터 스트림이라고 하며, '앞으로 생성될지도 모르는 데이터'까지도 포함하는 개념입니다.

 

쇼핑몰을 기존의 방식대로 만들자면, (주문 발생 -> 주문쪽에서 상품 재고 변경 호출)이 수행될 것입니다.
리액티브 프로그래밍에서는 (주문 발생 -> 상품쪽으로 상품 재고 변경 데이터 전달 -> 상품쪽에서 상품 재고 변경)이 수행됩니다. 객체의 책임이 달라지는 것이죠. 주문쪽은 데이터 전달까지만 책임지고 그 데이터로 상품쪽이 무엇을 하든 상관하지 않습니다.

 

이런 방식의 장점은 무엇일까요?

  

  • 데이터 생산측은 데이터 소비측이 데이터를 처리하는 도중이라도 다음 일을 처리할 수 있습니다. (non-blocking)
  • 최근 많이 사용되는 MSA를 구현하는 데 적합합니다.

Reactive Streams

Reactive Streams는 데이터 스트림을 비동기로 다룰 수 있게 하는 인터페이스입니다.
이 인터페이스를 구현하는 라이브러리, 프레임워크 등이 있는 것이죠. (RxJava, Reactor)

이 인터페이스의 구성을 보자면, PublisherSubscriber가 있습니다.

  

  • Publisher: 데이터를 통지하는 생산자
  • Subscriber: 데이터를 수신받아 처리하는 소비자

Reactive Streams 데이터 흐름

  1. Publisher가 통지 준비가 끝나면 이를 Subscriber에 통지합니다. (onSubscribe)
  2. 통지를 받은 Subscriber는 받고자 하는 데이터 개수를 요청합니다.
  3. Publisher는 데이터를 만들어 Subscriber에 통지합니다. (onNext)
  4. Subscriber는 받은 데이터를 이용하여 처리 작업을 수행합니다.
  5. Publisher는 다음 요청이 있을 때까지 데이터 통지를 중지합니다.
  6. 모든 데이터가 통지되었으면 정상 종료 되었다고 / 에러가 발생하였다고 통지합니다. (onComplete / onError)

Reactive Streams 인터페이스

Publisher

데이터를 생성하고 통지한다.

public interface Publisher<T> {
    public void subscribe(Subscriber <? extends T> subscriber);
}

Subscriber

통지된 데이터를 전달받아 처리한다.

public interface Subscriber<T> {
    public void onSubscribe(Subscription subscription);
    public void onNext(T item);
    public void onError(Throwable error);
    public void onComplete();
}

Subscription

데이터 개수를 요청하고 구독을 해지한다.

public interface Subscription {
    public void request(long num);
    public void cancel();
}

Processor

Publisher와 Subscriber를 모두 구현한다.

public abstract interface Processor<T, R> extends Subscriber<T>, Publisher<R> { }

Reactive Streams의 규칙

  • 구독 시작 통지는 해당 구독에서 한 번만 발생합니다.
  • 통지는 순차적으로 이루어집니다.
  • null은 통지하지 않습니다.
  • Publisher의 처리는 완료 또는 에러를 통지해 종료합니다.
  • Subscriber가 데이터 개수 요청에 Long.MAX_VALUE를 설정하면 데이터 개수에 의한 통지 제한은 없어집니다.
  • Subscriber의 메서드는 동기화된 상태로 호출해야 합니다. 즉, Subscription의 메서드(request, cancel)를 동시에 호출해서는 안 됩니다.

Reactor

Reactor는 위에서 살펴본 Reactive Streams의 구현체 중 하나로, JVM을 위한 라이브러리입니다.
스프링 프레임워크5에서 리액티브 프로그래밍의 기반이 되었습니다.
https://projectreactor.io/learn

Flux

  • Publisher의 구현체
  • 0 ~ N개의 데이터를 통지한다.
  • 생성하기: just, range, fromArray, fromIterable, fromStream, empty

Mono

  • Publisher의 구현체
  • 0 ~ 1개의 데이터를 통지한다.
  • 생성하기: just, empty

Spring WebFlux

Spring WebFlux는 기본이 되는 Reactor에 웹 개발에 필요한 기능들을 추가로 제공하는, Netty 기반의 웹 런타임입니다.
Build Reactive APIs with Spring WebFlux