Programming/Spring

Spring Webflux - Reactive Streams API 만들기[0]

긍정왕웹서퍼 2022. 10. 3. 15:38
728x90

개요

안녕하세요 이번에 Spring Webflux를 이용한 API를 만들면서 배웠던 것들을 정리해보려고 합니다.

처음 프로젝트를 만들기부터 심상치않았던 만큼, Java 와 Spring webflux 를 이용해 어떻게 개발했는지 정리해보겠습니다.

 

Spring Webflux - Reactive Streams란?

먼저 Reactive Streams 란게 무엇인지부터 찾아보겠습니다.  Reactive Streams 의 공식문서에서 소개된 문장입니다. 

논블로킹(non-blocking), 백 프레셔(back pressure)를 이용한 비동기(asynchronous) 데이터처리의 표준

기존의 처리방식은 데이터 처리요청을 받으면 모든 데이터를 처리한 후 메모리에 적재되어야만 응답메세지를 받았습니다.

하지만 Stream 방식은 데이터 파이프라인을 만들어 들어오는대로 유연하게 구독(Subscribe)하고 처리하여 발행(Publish)까지 한번에 처리할 수 있어서 많은 대용량의 데이터도 효율적으로 처리할 수 있습니다. 비동기식의 장점은 blocking 하지 않기때문에 지연되었을 때도 계속 다른일을 처리할 수 있어 적은 리소스로도 빠른속도로 처리가 가능합니다.

기존의 방식과 스트림 방식의 비교

 

이렇게 글을 보면 논블로킹과 비동기를 장점으로 Reactive Streams 를 사용한다는건 알겠는데 구독과 발행, 백 프레셔가 이해가 잘 안갑니다. 그래서 정리해 보자면 백프레셔(Back pressure)란 기존의 처리방식에서 쓰이던 발행자가 구독자에게 데이터를 밀어넣던 Push방식이 아닌, 새로이 등장하여 구독자가 처리할 수 있을때 발행자(Publisher)에게 요청하여 받아와 처리하는 방식으로 구독자(Subscriber)가 수용할 수 있는 만큼만 데이터를 요청하는 방식을 백프레셔라고 합니다. 

발행자(publisher)와 구독자(subscriber)의 메소드들

그렇다면 백프레셔의 개념을 알았지만 실제로 publisher 와 subscriber의 역할이나 기능들을 알아야 될거같습니다.

Publisher는 Reactive Stream으로 데이터를 발행하면, Subscriber가 구독한 상태에서 대기하다가 신호를 처리합니다.
실제 데이터의 처리(Transaction)시점은 Subsciption 시점에 이뤄집니다.

리액티브 스트림즈의 워크플로우(Reactive streams work flow)

  1. Subscriber 가 subscription 함수를 사용해 Publisher에게 구독을 요청
  2. Publisher는 onSubscribe 함수를 사용해 Subscription을 전달
  3. Subscription은 PublisherSubscriber 간의 통신 매개체로 연결을 담당
  4. Publisher는 Subscription 을 통해 Subscriber의 onNext에 데이터를 전달하고 정상적으로 작업이 완료되면 onComplete,
    문제가 생기면 onError를 전달
  5. SubscriberPublisher, Subscription이 서로 유기적으로 연결되어 통신을 주고받으며 subscripbe부터 onComplete까지의 연결을 통해 백프레셔가 완성

큰 흐름에 대해 이해가 되었다면 Publisher의 구현체이자 반환객체인 Mono 와 Flux에 대해 알아야합니다.

Mono : 0~1개의 데이터를 전달하는 객체
Flux : 0~N개의 데이터를 전달하는 객체

여기서 왜 0개는 null이랑 같은거아닌가 ? 왜 0개부터 반환하지 싶을 수 있는데, Publisher는 객체를 empty상태로 반환하는 메소드를 통해 빈값을 반환할 수 도 있어서 그렇습니다. 그러면 주요 Operator에 대해 알아보겠습니다. 물론 공통되지 않은 메소드들도 있습니다.

  • just("A") : 객체를 새로 생성해 초기화한다.
  • fromArray(new Integer[...]) : 배열을 생성한다.
  • from(publisher) : 다른 발행자(publisher) 를 Flux로 변환한다. 
  • empty : 빈값의 객체를 생성해 반환한다.
  • never : onComplete, onError 신호까지(subscription의 종료까지) 보내지않고 대기
  • error(throwble) : 오류(Exception)를 반환하는 시퀀스를 생성
  • defer(supplier) : 구독되는 순간에 supplier를 실행하여 시퀀스를 생성 

 

Webflux 는 Reactive Streams 의 프로그래밍방식을 기존의 WebMVC과 다른 리액티브한 프로그래밍을 위해 Spring 5.0 버전에 추가되었으며 비동기 데이터 스트림을 이용한 이벤트 기반의 처리방식으로 개발되었습니다.