본문 바로가기
Back-End/Spring WebFlux

리액티브 프로그래밍

by 달의 조각 2022. 10. 12.

리액티브 시스템

리액티브(Reactive)는 사전적으로 '반응을 하는', '반응을 보이는'라는 의미를 가진다. (리액션이 좋은 사람을 떠올려 보자!) 리액티브 시스템이란 클라이언트 요청에 반응을 잘하는 시스템을 의미한다. 이는 쓰레드의 Non-Blocking과 관련이 있다. 클라이언트의 요청에 대한 응답 대기 시간을 최소화하기 위해 요청 쓰레드가 차단되지 않게 함으로써 즉각적으로 반응할 수 있도록 구성된 시스템이다.

 

리액티브 선언문의 리액티브 시스템 설계 원칙

 

  • 방법(MEANS): 리액티브 시스템에서의 커뮤니케이션 수단
    👉 메시지 기반 통신으로 여러 시스템 간 느슨한 결합을 유지
  • 형태(FORM): 메시지 기반 통신을 통해 어떤 특성을 가지는 구조로 형성되었는가?
    👉 Elastic: 시스템에 들어오는 요쳥량과 상관없이 일정한 응답성을 유지
    👉 Resilient: 시스템 일부에 장애가 발생하더라도 응답성 유지
  • 값(VALUE): 리액티브 시스템의 핵심 가치가 무엇인가?
    👉 Responsive: 클라이언트 요청에 즉각적으로 응답할 수 있어야 한다.
    👉 Maintainable: 클라이언트 요청에 대한 즉각적인 응답이 지속되어야 한다.
    👉 Extensible: 클라이언트 요청에 대한 처리량을 자동으로 확장하고 축소할 수 있어야 한다.

 

리액티브 프로그래밍

Non-Blocking 통신과 유기적인 관계를 맺는 메시지 기반 통신(Message Driven)을 위한 프로그래밍 모델이다.

In computing, reactive programming is a declarative programming paradigm concerned with data streams and the propagation of change. With this paradigm, it's possible to express static (e.g., arrays) or dynamic (e.g., event emitters) data streams with ease, and also communicate that an inferred dependency within the associated execution model exists, which facilitates the automatic propagation of the changed data flow.
  • declarative programming paradigm
    선언형 프로그래밍 방식을 사용하는 대표적인 프로그래밍 모델
  • data streams and the propagation of change
    지속적으로 데이터가 입력으로 들어올 수 있고, 이는 데이터에 어떤 변경이 발생함을 의미(이벤트)
  • automatic propagation of the changed data flow
    지속적으로 발생하는 데이터를 하나의 데이터 플로우로 보고 데이터를 자동으로 전달

 

리액티브 스트림즈 - 컴포넌트

표준 사양(인터페이스)

🍌 Publisher

데이터 소스로부터 데이터를 내보내는(emit) 역할

// Publisher 인터페이스
public interface Publisher<T> {
    public void subscribe(Subscriber<? super T> s); // 파라미터 데이터가 내보내진 데이터를 소비하는 역할
}

🍌 Subscriber

Publisher로부터 내보내진 데이터를 소비하는 역할

public interface Subscriber<T> {
    public void onSubscribe(Subscription s); // 구독 시작 시 호출, 요청할 데이터 개수를 지정하거나 구독 해지 처리 가능
    public void onNext(T t); // Publicsher가 데이터를 emit 시 호출, 데이터를 전달받아서 소비
    public void onError(Throwable t); // emit 된 데이터가 전달되는 과정에서 에러 시 호출
    public void onComplete(); // emit 과정 종료 시 호출, 정상적으로 완료된 후 처리해야 할 작업이 있다면 이 안에서 수행
}

🍌 Subscription

Subscriber의 구독 자체를 표현한다.

public interface Subscription {
    public void request(long n); // publihser가 emit 하는 데이터의 개수
    public void cancel(); // 구독 해지: 더 이상 emit을 하지 않는다
}

🍌 Processor

Publicsher와 Subscriber의 역할을 동시에 할 수 있다.

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

 

리액티브 스트림즈 - 구현체

  • Project Reactor: 대표 구현체, Spring과 궁합이 가장 잘 맞다.
  • RxJava: .NET 기반 리액티브 라이브러리를 넷플릭스에서 Java 언어로 포팅한 JVM 기반 라이브러리
  • Java Flow API: 리액티브 스트림즈 표준 사양을 Java 안에 포함시킨 구조 - SPI(Service Provider Interface) 역할.
  • 기타 리액티브 확장(Reactive Extension): RxJava(대표적), RxJS, RxAndroid, RxKotlin, RxPython, RxScala

댓글