쏭의 개발 블로그

WebFlux에 대해서 본문

Back-end/Spring

WebFlux에 대해서

songu1 2023. 11. 7. 23:21

 

Spring 프로젝트에서 WebClient를 사용하여 Open API를 호출하도록 구현해보면서 Spring WebFlux와 WebClient에 대해서 학습을 했었다. (물론 Servlet 애플리케이션이어서 WebClient만 사용하긴 했지만!) 평소에 개인 노션에 기록해뒀는데 블로그에도 작성해보려고 한다!

 

[1] WebFlux란

클라이언트, 서버에서 Reactive 스타일의 애플리케이션 개발을 도와주는 스프링 모듈이다. 반응형 프로그래밍을 통해 높은 처리량과 확장성을 갖는 애플리케이션을 만드는 목적으로 reactive-stack web framework로 non-blocking과 reactive stream을 지원한다.

 

특징

  • Single-Thread와 Non-Blocking 방식을 사용하여 적은 수의 스레드를 사용하여 여러 클라이언트의 요청을 처리할 수 있다
  • Reactive Streams 사양을 기반으로하여 비동기적인 이벤트 지향 프로그래밍을 통해 높은 확장성과 성능을 제공한다.
  • 반응형 프로그래밍(Reactive Programming)을 구현하기 위해 Reactor라는 라이브러리를 사용한다.

장점

  • 고성능
  • Spring과 완벽한 통합
  • netty 지원
  • 비동기 non-blocking I/O으로 성능을 끌어올릴 수 있다.

단점

  • 오류처리가 다소 복잡하다.

 

[2] Spring MVC vs WebFlux

공통점

  • 컨트롤러, Reactive 클라이언트
  • 톰캣, jetty, undertow와 같은 서버에서 실행가능

차이점

[1] Spring MVC

  • 명령형 논리, JDBC, JPA를 가질 수 있다.
  • 하나의 요청에 대해 하나의 스레드를 제공하므로 다량의 요청을 대비해 미리 스레드 풀을 생성하고 각 요청마다 스레드를 할당하여 처리한다.
  • 동기 + 블로킹
  • 작성하고 디버그하는 쉬운 방법인 명령형 프로그래밍을 사용한다

[2] WebFlux

  • 기능적 엔드 포인트, 이벤트 루프, 동시성 모델을 가질 수 있다.
  • Netty 서버에서 실행 가능하다
  • 서버는 스레드 1개로 운영,  cpu 코어 수 개수의 스레드를 가진 work pool을 생성하여 해당 워커 풀 내의 스레드로 모든 요청을 처리한다
  • 비동기 + 논블로킹 방식이므로 블로킹 라이브러리가 필수적으로 사용되어야한다면 worker thread가 아닌 외부 별도의 thread로 요청을 처리해야한다.

그렇다면 Spring MVC와 WebFlux를 모두 사용하는 방법에는 마이크로서비스 아키텍처의 방법이 있다. 

 

 

[3] Reactive Programming 반응형 프로그래밍

Spring WebFlux는 반응형 프로그래밍 방식을 통해 이벤트 기반의 비동기식 애플리케이션을 구축할 수 있다. Reactive Programming는 데이터 스트림을 이용하여 전달하고 데이터 변경 시점을 이벤트로 하여 수신자와 송신자 사이에 데이터를 전달시키는 비동기 프로그램이다. 즉, 새로운 이벤트가 발생하면 이벤트 스트림이 생성되며 스트림을 구독하여 이벤트를 처리할 수 있다.

 

명령형 프로그래밍은 컴퓨터가 수행해야하는 일을 명령의 목록으로 나열하고 이를 순서대로 실행하는 것으로 대부분 동기적이다. 반응형 프로그래밍은 데이터 스트림을 처리하며 데이터 스트림이 변경될 때마다 반응하는 것으로 대부분 비동기적이라고 할 수 있다.

 

[4] Reactor

Reactive Programming을 구현하기 위한 Reactive 라이브러리 중 하나로 JVM 위에서 동작하는 논블로킹 애플리케이션을 만들기 위한 Reactive 라이브러리이다. Publisher-Subscriber 패턴을 중심으로 동작하며 데이터 생성, 가공하고 구독자에게 전달하는 역할을 수행하고 Mono와 Flux의 데이터 스트림 유형을 지원한다.

 

Publisher-Subscriber 패턴

Publisher-Subscriber 패턴은 Publisher가 데이터를 생성하고 Subscriber가 이를 소비하는 방식으로 데이터를 효율적으로

처리할 수 있는 패턴이다.

 

각 객체 요소들은 다음과 같다.

 

반응형 프로그래밍에서 데이터 처리를 수행하는 반응형 스트림의 처리 과정은 아래와 같다.

  1. [subscribe] Subscriber가 Publisher에 등록하고 데이터 스트림을 수신할 준비가 되었음을 Publisher에게 알림
  2. [onSubscribe] Publisher가 Subscriber에게 데이터 스트림 전송을 시작하기전에 호출되는 메소드
    이 메소드를 통해 Subscriber는 Subscription 객체를 받아들여 데이터 양을 제어 가능
  3. [request(n)/cancel]cancel 메소드 : 데이터 스트림을 취소
    request(n) 메소드 : Publisher에게 n개의 데이터를 요청
  4. [onNext(data)] Publisher가 생성한 data를 Subscriber에게 전달 (데이터가 전송될때마다 호출됨)
  5. [onComplete/onError] Publisher가 모든 데이터를 전송 완료한 후 더 이상 데이터가 없을 때 호출됨
    onComplete 메소드 : 모든 데이터가 성공적으로 전송되었음을 나타냄
    onError 메소드 : 데이터 전송 중 오류가 발생했음을 나타냄

 

Mono 와 Flux

Mono

  • 0~1개의 데이터 전달
  • 오직 0개 또는 1개의 데이터항목을 생성하고 스트림이 종료되면 결과 생성 종료
  • 여러 스트림을 하나의 결과로 모아줄 때 사용
  • Mono를 사용하여 비동기적으로 결과를 반환 → 결과를 구독하는 클라이언트는 결과가 생성될 때까지 블로킹하지 않고 다른 작업을 수행 가능

Flux

  • 0~n개의 데이터 전달
  • 여러개의 데이터 항목을 생성하고 스트림이 종료되면 결과 생성을 종료
  • 각각의 Mono를 합쳐서 여러개의 값을 Flux로 처리
  • Spring WebFlux에서 Flux를 사용하여 HTTP 요청을 처리하는 경우, 요청을 수신한 즉시 해당 요청을 처리하고 결과를 생성하는 대신 결과 생성이 완료될때까지 다른 요청 처리 가능

Multi Event Loop

multi event loop는 Reactor Core에서 지원을 하며 단일 스레드로 동작하는 이벤트 루프를 여러개 사용하는 것이다. 블로킹 I/O 작업이 발생하더라도 다른 이벤트 루프를 통해 애플리케이션이 멈추지 않고 계속 동작한다.

  1. Event Queue
    이벤트가 발생하면 해당 이벤트를 처리하기 위한 콜백함수를 저장
  2. Process Events
    이벤트 루프는 이벤트 큐에서 이벤트를 하나씩 가져와 처리
  3. Event Loop
    주어진 작업을 처리
  4. Register Callback
    작업을 처리하기 위한 콜백 함수를 등록
  5. Intensive Operation(Platform)
    블로킹 I/O 작업이 발생하면 이벤트 루프는 해당 작업을 처리하기 위한 새로운 스레드를 생성
  6. Operation Completion
    블로킹 I/O 작업이 완료되면 결과를 이벤트 루프에 알리고 새로운 스레드는 종료
  7. Trigger Callback
    이벤트 루프는 결과를 처리하고 다른 작업을 처리

 


https://devuna.tistory.com/108

https://velog.io/@rnqhstlr2297/Spring-Webflux와-WebClient

https://devuna.tistory.com/120

https://adjh54.tistory.com/232

'Back-end > Spring' 카테고리의 다른 글

Spring Boot와 Redis 연동(2) : Redis Serializer  (0) 2025.05.04
Spring Boot와 Redis 연동 (+연동 시 고민사항)  (0) 2025.04.27
DAO, DTO, VO, Domain 차이  (0) 2023.10.07
@Controller와 @RestController 차이  (0) 2023.10.07
Spring AOP  (0) 2023.10.07