ch17. 리액티브 프로그래밍

    리액티브 프로그래밍의 중요성

    • 빅데이터: 기가 바이트의 데이터 → 페타 바이트 단위의 데이터
    • 다양한 환경: 모바일 디바이스에서 부터 클라우드 기반 클러스터에 이르기까지 다양한 환경에 애플리케이션이 배포됨
    • 사용자 패턴: 사용자는 1년 내내 항상 서비스를 이용할 수 있으며, 밀리초 단위의 응답시간을 기대함

     

    리액티브 프로그래밍: 다양한 시스템과 소스에서 들어오는 데이터 항목 스트림을 비동기적으로 처리하고 합쳐서 해결함

     

    17.1 리액티브 매니패스토

    리액티브 애플리케이션과 시스템 개발의 핵심 원칙을 공식적으로 정의함

    • 반응성(responsive): 빠르고 일정하고 예상가능한 반응 시간을 제공함
    • 회복성(resilient): 장애가 발생해도 시스템은 반응해야 함
    • 탄력성(elastic): 애플리케이션에 작업 부하가 심해지면 자동으로 컴포넌트에 할당된 자원 수를 늘림
    • 메시지 주도(Messge-driven): 비동기 메시지를 전달해 컴포넌트끼리의 통신이 이루어짐. 회복성과 탄력성을 지원하려면 시스템을 구성하는 컴포넌트의 경계를 명확하게 정의해향함. 
      • 회복성: 장애를 메시지로 처리
      • 탄력성: 주고받은 메시지 수를 감시하고 메시지 양에 따라 적절하게 리소스를 할당

     

    17.1.1 애플리케이션 수준의 리액티브 (리액티브 애플리케이션)

    • 주요 기능 비동기로 작업을 수행
    • 이벤트 스트림을 블록하지 않고 비동기로처리하는 것이 멀티코어 CPU의 사용률을 극대화할 수 있음
    • 리액티브 프레임워크 & 라이브러리는 스레드를 이벤트 루프 등과 공유하고, 처리할 이벤트를 관리함. 비동기 애플리케이션 구현의 추상 수준을 높일 수 있으므로 동기 블록, 경쟁 조건, 데드락 같은 저 수준의 멀티스레드 문제를 직접 처리하지 않아도 됨
    • 스레드를 다시 쪼개는 종류의 기술을 사용할 때 메인 이벤트 루프 안에서 동작을 블록하지 않아야 함
      • RxJava, Akka와 같은 리액티브 프레임워크는 별도로 지정된 스레드 풀에서 블록 동작을 실행시켜 문제를 해결함.메인 풀의 모든 스레드는 방해받지 않고 실행되므로 모든 CPU 코어가 가장 최적의 상황에서 동작할 수 있음. CPU 관련 작업과 I/O 관련 작업을 분리하면 더 정밀하게 풀의 크기를 설정할 수 있고, 두 타입의 작업의 성능을 관찰할 수 있음

     

     

    17.1.2 시스템 수준의 리액티브 (리액티브 시스템)

    • 리액티브 시스템
      • 여러 애플리케이션이 하나의 일관적인, 회복 가능한 플랫폼을 구성할 수 있게 함
      • 애플리케이션들 중 하나가 실패해도 전체 시스템은 계속 운영될 수 있도록 도와주는 소프트웨어 아키텍쳐
      • 애플리케이션을 조립하고 상호소통을 조절함. 메시지 주도가 특징임

     

    • 리액티브 어플리케이션
      • 리액티브 시스템을 구현한 어플리케이션
      • 비교적 짧은 시간 도안만 유지되는 데이터 스트림에 기반한 연산을 수행하며 보통 이벤트 주도로 분류됨.
        • 메시지는 정의된 목적지 하나를 향하는 반면, 이벤트는 관련 이벤트를 관찰하도록 등록한 컴포넌트가 수신한다는 점이 다름.

     

    리액티브 시스템

    • 고립&비결합(회복성): 수신자와 발신자가 수신 메시지와 발신 메시지를 결합하지 않도록 이 메시지들을 비동기로 처리해야 함. 각 컴포넌트를 완전히 고립하려면 이들을 결합되지 않도록 해야함. 이를 통해 시스템이 장애와 높은 부하에서도 반응성을 유지할 수 있음
    • 위치 투명성(탄력성): 리액티브 시스템의 컴포넌트들이 물리적인 위치에 대한 정보를 알 필요 없이 서로 통신할 수 있음. 즉, 어떤 컴포넌트가 다른 컴포넌트에게 메시지를 보낼 때, 그 컴포넌트가 물리적으로 어디에 위치해 있는지 몰라도 메시지를 보낼 수 있어야 함. 시스템의 위치 정보가 추상화되어 있기 때문에 시스템을 쉽게 복제할 수 있으며 현재 작업 부하에 따라 자동으로 애플리케이션을 확장할 수 있음

     

     

    17.2 리액티브 스트림과 플로 API

    • 리액티브 프로그래밍: 리액티브 스트림을 사용하는 프로그래밍
    • 리액티브 스트림: 잠재적으로 무한한 비동기 데이터를 순서대로 그리고 블록하지 않는 역압력을 전재해 처리하는 표준 기술
    • 역압력
      • 목적지 스트림에서 처리할 수 있는 양보다 소스 스트림에서 생성되는 양이 더 많을 때 발생.
      • 소스 스트림에서는 목적지 스트림으로 더 이상 데이터를 전송하지 않음
      • 시스템 전체에서 과부하가 발생하는 것을 방지할 수 있음

     

     

    17.2.1 Flow 클래스 소개

    java9의 java.util.concurrent.Flow

    Pub-Sub 모델을 지원할 수 있도록 인터페이스를 제공함

     

    • Publisher
      • 함수형 인터페이스
      • 항목 발행
      • Subscriber의 요구사항에 따라 역압력 기법에 의해 이벤트 제공 속도가 제한됨
    • Subscriber
      • Publisher가 발행한 이벤트 리스너
      • 한 개씩 또는 한 번에 여러 항목을 소비
    • Subscription
      • Publisher와 Subscriber 사이의 제어 흐름, 역압력을 관리
    • Processor

     

    Publisher & Subscriber

    @FunctionalInterface
    public interface Publisher<T>{
    	void subscribe(Subscriber<? super T> s);
    }
    public interface Subscriber<T>{
    	void onSubscribe(Subscription s);
        void onNext(T t);
        void onError(Throwable t);
        void onComplete();
    }
    • 순서를 지켜야함
      • onSubscribe onNext* (onError | onComplete)?
      • onSubscribe → onNext 0~무한번 → 끝나려면 onError or onComplete 중 하나로 끝나기
    • Subscriber가 Publisher에 자신을 등록할 때, Publisher는 onSubscribe 메서드를 호출해서 Subscription 객체를 전달함

     

    Subscription

    public interface Subscription{
    	void request(long n);
        void cancel();
    }
    • Subscription 인터페이스는 메서드 두 개를 정의함
      • request(long n): Publisher에게 n개의 이벤트를 처리할 준비가 되었음을 알림
      • cancel(): Subscription을 취소함. Publisher에게 더 이상 이벤트를 받지 않음을 통지함

     

     

    • Publisher는 반드시 Subscription의 request 메서드에 정의된 개수 이하의 요소만 Subscriber에게 전달해야 함
    • Subscriber는 요소를 받아 처리할 수 있음을 Publisher에 알려야 함 (역압력)
    • Pub-Sub은 정확하게 Subscrption을 공유해야하며 각각이 고유한 역할을 수행해야 함

     

    Processor

    public interface Processor<T,R> extends Subscriber<T>, Publisher<R> {
    
    }
    • Processor interface
      • 리액티브 스트림에서 처리하는 이벤트의 변환 단계를 나타냄
      • Processor가 에러를 수신하면 이로부터 회복하거나 즉시 onError 신호로 모든 Subscriber에게 에러를 전파할 수 있음
      • Subscriber가 Subscription을 취소하면 Processor는 자신의 업스트림 Subscription도 취소하므로 취소 신호를 전파해야함

    댓글

    1. 17.1 리액티브 매니패스토
      1. 17.1.1 애플리케이션 수준의 리액티브 (리액티브 애플리케이션)
      2. 17.1.2 시스템 수준의 리액티브 (리액티브 시스템)
    2. 17.2 리액티브 스트림과 플로 API