Spring Boot Webflux

ayboori·2024년 10월 4일
0

Spring

목록 보기
24/24

Spring Boot Webflux란?

  • 반응형 스택 웹 프레임워크
  • non-blocking
  • 비동기 처리
  • 적은 수의 스레드로 동시성을 처리 / 적은 하드웨어 리소스로 확장
  • 반응형 프로그래밍을 통해 '높은 처리량'과 '확장성'을 갖는 애플리케이션을 만드는 것을 목표
  • Netty, Undertow와 같은 Non-Blocking I/O 서버를 기반으로 동작

Spring MVC와의 비교

  • Spring MVC와 WebFlux 컨트롤러의 혼합 어플리케이션을 가질 수 있다.

반응형 프로그래밍(Reactive Programming)

  • 스레드 대신 데이터 스트림에 초점
  • 변화에 반응하는 것을 중심으로 구축된 프로그래밍 모델
    - 이벤트 처리, UI 업데이트 등
  • 비차단 = 반응형
    - 차단 대신 작업 완료, 데이터 사용 가능 등의 알림에 반응한다.

이를 통해 ‘이벤트 기반의 비 동기식 애플리케이션’을 구축할 수 있다.

사용할 수 있는 DB

  • WebFlux로 개발하고 DB는 blocking이라면? WebFlux를 쓸 이유가 없다. 라는 개념 아래서 reactive를 지원하는 DB를 사용해야 한다.
  • 우리가 일반적으로 알고있는 RDBMS는 지원하지 않고 Redis, Mongo 등은 지원한다.

사용하는 이유

  • 많은 트래픽을 소화하는 시스템에 도입하여 리소스 최적화

  • Spring MVC는 1:1로 요청을 처리하기 때문에 트래픽이 몰리면 많은 쓰레드가 생겨난다.
    쓰레드가 전환될 때 문맥교환(context switching) 비용이 발생하게 되는데 쓰레드가 많을수록 비용이 커지기 때문에 적절한 쓰레드 수를 유지해야 하는 문제가 있다.

  • 이에 반해, WebFlux는 Event-Driven 과 Asynchronous Non-blocking I/O를 통해 리소스를 효율적으로 사용할 수 있다.

구성 요소

Reactor

  • Spring WebFlux를 위한 선택의 반응형 라이브러리
    • Reactor를 핵심 종속성으로 필요로 하지만 Reactive Streams를 통해 다른 반응형 라이브러리와 상호 운용 가능
  • Reactive 라이브러리 중 하나
  • Publisher-Subscriber 패턴을 중심으로 동작하며 데이터를 생성하고 가공하고 구독자에게 전달하는 역할
  • Reactor에서는 Mono와 Flux의 데이터 스트림 유형을 지원
  • 모든 연산자가 비차단 백프레셔를 지원

백프레셔(BackPressure)

  • 비동기 스트림 처리에서 데이터의 양을 제어하는 것을 의미합니다. 발행자(Publisher)가 생성한 데이터를 구독자(Subscriber)가 처리할 때 구독자가 처리할 수 있는 데이터 양을 초기화하여 데이터가 생성되는 상황을 방지하기 위해 백 프레셔를 사용합니다.

  • 백프레셔는 Subscriber가 처리할 데이터의 양을 Subscription(구독)을 통해 제어하며, Publisher는 Subscriber의 처리 속도에 맞춰 데이터를 생성합니다. 이를 통해 Subscriber가 처리할 수 있는 양 이상의 데이터가 생성되는 상황을 방지하고, 시스템의 안정성을 보장할 수 있습니다.

Publisher-Subscriber 패턴: 반응형 스트림(Reactive Stream)

💡 반응형 스트림(Reactive Stream)

  • 비 동기적 및 이벤트 기반 응용 프로그램을 위한 ‘스트림 처리 기술’을 의미합니다. 해당 기술의 핵심은 ‘Publisher’가 ‘Subscriber’에게 데이터를 제공하는 것을 의미합니다.

  • 이는 Publisher는 데이터를 생성하고 Subscriber는 이를 처리합니다. 이러한 방식으로 스트림을 처리함으로써 데이터를 더 효율적으로 처리할 수 있습니다.

Mono / Flux

구현 참고

  • Flux와 Mono는 Reactor 객체 / Reactor 라이브러리에서 제공하는 Reactive Streams의 구현체 중 하나입니다.
  • 목적하는 갯수의 데이터 항목을 생성하고, 이 결과가 생성되고 나면 스트림이 종료되면서 결과 생성을 종료합니다.
  • 차이점은 발행하는 데이터 갯수입니다.

Mono

  • 0~1 개의 데이터 전달
    - int / char 등의 개념으로 생각

Flux

  • 0~N 개의 데이터 전달
    - List / 배열 등의 개념으로 생각

blocking / non-blocking Request

blocking Request

  • 기존 Spring MVC에서 사용되던 Blocking Request를 수행하면서 클라이언트에서 요청을 보내면 결과가 반환될 때까지 대기를 하는 것을 의미합니다.

non-blocking Request

  • webflux에서 제공하는 Non-Blocking Request을 수행하면서 요청을 보내고 결과가 반환되지 않더라도 다른 작업을 수행할 수 있는 것을 의미합니다.
  • Event Handler을 통해 DB에 요청을 보내고, Event를 응답 받습니다. 그 동안 Event Loop 내에서는 적은 수의 스레드르르 수행하며 다른 작업을 수행합니다.

Multi Event Loop

  • Reactor Core에서 지원을 하며 단일 스레드로 동작하는 ‘이벤트 루프를 여러 개 사용’하는 것을 의미합니다. 이를 통해 블로킹 I/O 작업이 발생하더라도 다른 이벤트 루프를 통해 애플리케이션이 멈추지 않고 계속 동작할 수 있습니다.

WebClient

  • WebFlux의 일부인 Webclient는 비동기적인 방식으로 HTTP 요청을 보내고 응답을 받을 수 있는 라이브러리를 의미합니다.
  • 다수의 외부 API 호출이나, 다른 서비스들과의 통합 작업에서 유용합니다.
  • WebFlux의 WebClient는 비동기적인 방식으로 HTTP 요청을 보내고 응답을 받을 수 있는 라이브러리입니다. 이를 통해 Reactive Streams를 이용하여 높은 성능의 네트워크 통신을 구현할 수 있습니다.
WebClient webClient = WebClient.builder().build();

Mono resultMono = webClient.get()
        .uri("<https://www.example.com/>")
        .retrieve()
        .bodyToMono(String.class);

String result = resultMono.block();

System.out.println(result);

MVC 환경에서는 WebFlux와 달리 블로킹 I/O를 사용하기 때문에, 동기적인 작업을 수행할 때는 RestTemplate를 사용하는 것이 적합하다.

이후 부분은 참고 링크%20%EC%A3%BC%EC%9A%94%20%EA%B5%AC%EC%84%B1%EC%9A%94%EC%86%8C%20%ED%99%95%EC%9D%B8-1) 전체 참고

참고 1 : Webflux의 흐름, 주요 구성 요소
참고 2 : 간단한 요약
참고 3 : Webflux 구현 / + WebSockets로 채팅 구현
참고 4 : 사용하는 이유
참고 5 : 성능 테스트 / 구현
참고 6 : Spring.io에서 제공하는 기본 코드 분석

profile
프로 개발자가 되기 위해 뚜벅뚜벅.. 뚜벅초

0개의 댓글