[해커톤] 리액티브 프로그래밍

nayoon·2021년 4월 30일
1

woori-hackathon

목록 보기
2/3

참고 사이트

3월 우아한 Tech 세미나 후기
(조졸두님이 세미나 후기를 적으면서 블로그를 활동을 더 왕성하게 했다는 이야기를 봤던 거 같은데 세미나 후기는 처음 읽어본당..)

Reactive Programming 101:리액티브 프로그래밍이 뭔가요

Spring WebFlux 리액티브 프로그래밍 개념 잡기 1 (기초, 용어)

Project Reactor 3. 리액티브 스트림

Project Reactor 4. Flux, Mono

리액티브 프로그래밍

  • 리액티브 프로그래밍은 생성자가 소비자를 압도하지 못하게 하는 목적이 핵심인 배압을 가지고 작은 수의 쓰레드로 확장성이 있는 논블로킹/이벤트 드리븐 개발
  • 함수형 프로그래밍
    • 리액티브 프로그래밍은 함수형 프로그래밍을 기반으로 한다.
  • 여러 API를 취합해서 전달해야하는 시스템에서는 각 API들의 경과 시간 전체 합산 시간만큼 필요.
  • 반대로 리액티브로 진행할 겨우 여러 API 중 가장 긴 경과 시간이 전체 시간
  • 코드 가독성이 쓰레드 모델보다는 훨씬 읽기 힘들다는 단점이 존재
  • NodeJS처럼 Spring처럼 쓰고자 등장

사용하려고 하는 이유

현재 API를 n개 호출해야하는데, 호출하고 결괏값을 모두 받을 때까지 다른 일을 할 수 없고 n개의 요청 시간을 모두 합친만큼 걸릴 것이다. 하지만, 리액티브 시스템을 사용하면 요청을 비동기적으로 동시에 보내기 때문에 이 중 가장 긴 요청만큼만 걸린다.

동기/비동기

동기, 비동기는 호출하는 요청자의 입장에서 생각해야 한다.

  • 동기 방식은 요청을 보내면 결과가 올 때까지 대기하는 방식
  • 비동기 방식은 요청을 보내고 결과를 통보받는 방식
    • 요청한 내용에 대한 '호출(Callback)'이 있을 때 개입

블로킹/논블로킹

블로킹, 논블로킹은 동기, 비동기와는 다르게 요청자, 제공자 둘다의 입장에서 생각해야 한다.

  • 블로킹은 하나의 작업을 처리할 때 호출된 작업이 끝날 때까지 호출한 작업이 기다리는 방식
  • 논블로킹은 블로킹의 반대로 하나의 작업을 처리할 때 호출한 작업이 끝나는 것을 기다리지 않고 결과를 발행/구독 형태로 통지하는 방식

Spring WebFlux는 비동기, 논블로킹 형태로 구성이 되며 모든 함수간의 관계가 발행/구독 형태의 옵저버 패턴으로 연결이 된다.

하나의 작업이 Thread에서 처리될 때 IO작업이 있다면 IO 작업을 맡은 Thread에게 완료되면 '호출'해줘라고 일을 위임하고 다른 일을 시작한다.

Reactive Streams

Description

"Reactive Streams"는 2013년 넷플릭스, 피보탈, 타이브세이프의 개발자들이 발의해서 처음 만들어졌는데, "리액티브 프로그래밍"을 위한 명세(specification)이다.
비즈니스 시스템 개발자는 "Reactive Streams"에 정의된 인터페이스를 구현하면 "리액티브 프로그래밍"을 구현할 수 있다.

Reactive Streams Interface

  • Processor
  • Publisher
  • Subscriber
  • Subscription

Reactive Streams에 정의된 코드는 다음과 같다. 구현체가 따로 필요한데, 가장 많이 사용되는 구현체 라이브러리는 RxJava이고 그 외에 Project Reactor 등이 있다.

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

public interface Publisher<T> {
    public void subscribe(Subscriber<? super T> s);
}

public interface Subscriber<T> {
    public void onSubscribe(Subscription s);
    public void onNext(T t);
    public void onError(Throwable t);
    public void onComplete();
}

public interface Subscription {
    public void request(long n);
    public void cancel();
}
  1. Subscriber가 Publisher에게 subscribe하면 Publisher가 데이터 또는 시퀀스를 전달하게 된다.
  1. 전달하기 전에 Publisher는 Subscribe에 정의된 onSubscribe()를 호출하고, Subscriber는 request(n)를 호출하여 몇 개의 데이터를 보내달라고 요청하게 된다.
  1. 이 때 Subscription을 사용하는데, request(n)을 호출하여 데이터 전송 요청을 하게 되면 Publisher에서는 0에서 N개의 데이터 또는 시퀀스를 Subscriber에 전달하게 된다.
  1. 이 과정에서 에러가 발생하면 onError()를 호출하고, 데이터(시퀀스) 전달이 완료가 되면 onComplete()를 호출한다.
  1. Subscriber가 Publisher에 Request하는 과정을 보통 Back-Pressure라고 표현하는데, Push하는 데이터(시퀀스)의 흐름을 제어할 수 있다. Request(1)을 호출하면 1개만 보내도록 요청할 수 있고, Request(MAX)를 호출하면 최대값에 해당하는 데이터를 요청하게 된다.

Reactor

Reactor는 "Reactive Streams"의 구현체로서, JVM을 위한 논블록킹 리액티브 프로그래밍 라이브러리이다. 스프링5에서 제공하는 리액티브 프로그래밍은 모두 Reactor를 기반으로 구현되어 있다.

reactor3의 핵심 모듈인 "reactor-core"는 Spring Webflux에 이미 포함되어 있다.

Publisher 구현체, Flux와 Mono

Reactor의 핵심은 Flux와 Mono인데, "Reactive Streams" 인터페이스 중에서 데이터(시퀀스)를 제공하는 발행자 역할을 하는 Publisher의 구현체이다.

Flux는 0-N 개의 데이터를 전달.
Mono는 0-1 개의 데이터를 전달.

Flux

Flux 는 Reactive Streams에서 정의한 Publisher의 구현체로서, 0-N 개의 데이터를 발행(전달, 방출)할 수 있다. 하나의 데이터를 전달할 때마다 onNext 이벤트를 발생한다. Flux 내의 모든 데이터의 전달 처리가 완료되면 onComplete 이벤트가 발생하며, 데이터를 전달하는 과정에서 오류가 발생하면 onError 이벤트가 발생한다.

Mono

Mono 는 Reactive Streams에서 정의한 Publisher의 구현체로서, 0-1 개의 데이터를 처리한다.

profile
뚜벅뚜벅 열심히 공부하는 개발자

0개의 댓글