Spring/Springboot

[Springboot] Spring WebFlux

늘이 2024. 9. 11. 15:22

 

1. Spring WebFlux 개요

Spring WebFlux는 Reactive Programming을 지원하는 스프링의 웹 프레임워크로, Spring 5부터 도입되었습니다. Reactive Programming은 비동기 데이터 스트림을 기반으로 시스템이 높은 성능을 유지할 수 있게 해주는 프로그래밍 패러다임입니다. WebFlux는 내부적으로 Project Reactor를 사용하며, 비동기 스트림을 처리하기 위한 두 가지 주요 개념인 FluxMono를 제공합니다.

  • Flux: 여러 개의 데이터를 비동기적으로 스트리밍하는 Publisher의 구현체.
  • Mono: 단일 데이터(혹은 없을 수도 있음)를 비동기적으로 처리하는 Publisher의 구현체.

Spring WebFlux는 비동기적이며 논블로킹 방식으로 작동하여, 높은 성능을 요구하는 웹 애플리케이션에 적합합니다.

 

 

2. Spring WebFlux의 두 가지 프로그래밍 모델

Spring WebFlux는 두 가지 프로그래밍 모델을 지원합니다:

1. Annotation-based (어노테이션 기반)

@RestController
public class MyController {
    @GetMapping("/hello")
    public Mono<String> hello() {
        return Mono.just("Hello, WebFlux");
    }
}
  • Spring MVC와 유사하게, 컨트롤러 클래스에 어노테이션을 사용하여 라우팅 및 요청 처리를 구성합니다.
  • 예를 들어 @RestController와 같은 어노테이션을 사용해 요청을 처리합니다.

2. Functional routing and handling (함수형 라우팅과 핸들링)

RouterFunction<ServerResponse> route = RouterFunctions.route()
    .GET("/hello", request -> ServerResponse.ok().body(Mono.just("Hello, WebFlux"), String.class))
    .build();
  • 람다식을 활용하여 함수형으로 요청 라우팅과 처리를 구성할 수 있습니다.
  • RouterFunction과 HandlerFunction을 사용하여 비동기 웹 요청을 처리합니다.

 

 

3. Reactor Netty와 비동기/논블로킹 동작 방식

Spring WebFlux는 기본적으로 Reactor Netty를 사용하여 비동기 논블로킹 서버를 실행합니다. Reactor Netty는 고성능 네트워크 애플리케이션을 위한 비동기 Event-driven 프레임워크입니다.

Netty의 주요 특징:

  • 비동기적 Event-driven 아키텍처: 요청이 발생하면 그 즉시 응답이 처리되고, 요청을 기다리지 않기 때문에 많은 트래픽을 효율적으로 처리할 수 있습니다.
  • 높은 동시성 처리: 네트워크 요청을 처리할 때 대기 상태 없이 작업을 진행하며, 수많은 요청을 병렬로 처리할 수 있습니다.

 

4. Netty의 작동 방식

Netty는 클라이언트 요청을 비동기적으로 처리하는 이벤트 기반 서버입니다. 이 서버는 클라이언트와 서버 사이에서 네트워크 연결을 관리하는 방식에서 주로 **채널(Channel)**과 이벤트 루프(Event Loop) 개념을 사용합니다.

Channel과 Connection

  • 클라이언트가 서버에 요청을 보내면, Netty는 클라이언트와 서버 간의 ConnectionChannel을 통해 관리합니다.
  • Channel은 서버와 클라이언트 사이의 통신 경로를 의미합니다. 이 통신 경로를 통해 요청을 받고, 응답을 보내는 역할을 합니다.

이벤트 루프(Event Loop)

  • Netty는 **이벤트 루프(Event Loop)**를 사용하여 네트워크 이벤트(요청, 응답 등)를 처리합니다. 이 이벤트 루프는 FIFO(First In, First Out) 방식의 이벤트 큐로 구성되어 있습니다.
  • 각 요청(또는 이벤트)은 이벤트 루프 내의 큐에 들어가며, 이벤트 루프는 이 큐에서 하나씩 이벤트를 꺼내어 처리합니다. 이 방식은 요청을 효율적으로 처리하고 병목을 방지할 수 있습니다.

ChannelHandler와 처리 로직

  • Netty는 요청이 들어올 때, 요청을 처리할 **핸들러(ChannelHandler)**를 찾아 호출합니다. 이 핸들러는 클라이언트의 요청에 맞는 정확한 엔드포인트를 찾아내는 역할을 합니다.
  • Spring WebFlux에서는 이 핸들러가 @RestController나 함수형 웹 라우팅 방식으로 정의된 엔드포인트입니다. 이를 통해 클라이언트 요청을 받아 응답을 처리하게 됩니다.

 

5. Netty의 Non-blocking 동작

Netty는 논블로킹(Non-blocking) 방식으로 작동합니다. 요청이 들어오면 Netty는 Future를 반환하여 클라이언트에게 즉시 응답을 줄 수 있습니다. 이 방식 덕분에 요청이 완료될 때까지 대기할 필요 없이 애플리케이션이 다른 작업을 진행할 수 있습니다.

  • 클라이언트가 서버에 요청을 보낼 때, Netty는 이를 즉시 처리하는 대신 비동기적 응답을 준비하고, 클라이언트는 기다리지 않고 계속해서 다른 작업을 할 수 있습니다.
  • 작업이 완료되면 이벤트로 응답을 받으며, Netty는 이를 이벤트 큐에 추가하고 이벤트 루프가 이를 처리하게 됩니다.

 

6. Netty의 대규모 연결 처리 능력

Netty의 비동기적이고 이벤트 기반의 아키텍처 덕분에 많은 수의 연결을 동시에 처리할 수 있습니다. 일반적으로 블로킹 I/O 방식에서는 클라이언트의 요청마다 서버의 스레드가 할당되어 자원을 소비하게 되지만, Netty는 논블로킹 I/O 방식을 통해 스레드를 효율적으로 사용하여 동시에 많은 클라이언트 요청을 처리할 수 있습니다.

 

7. Netty와 Spring WebFlux 연동

  • Spring WebFlux와 Netty는 기본적으로 잘 연동되며, Spring Boot에서 Reactor Netty를 기본 서버로 사용합니다.
  • 비동기 논블로킹 애플리케이션을 구축하는 데 있어 Netty가 서버 역할을 담당하고, Spring WebFlux는 이를 기반으로 비동기적으로 요청을 처리하며, FluxMono를 통해 비동기 스트림을 관리합니다.

 

8. 요약

  • Spring WebFlux는 비동기 논블로킹 방식의 웹 애플리케이션을 위한 프레임워크로, FluxMono를 사용하여 비동기 데이터 스트림을 처리합니다.
  • Reactor Netty는 비동기적 이벤트 기반 네트워크 프레임워크로, Spring WebFlux에서 기본 서버로 사용되며 높은 성능대규모 연결 처리 능력을 제공합니다.
  • Netty의 이벤트 루프는 각 요청을 **채널(Channel)**로 관리하며, 요청에 맞는 **핸들러(ChannelHandler)**를 찾아 클라이언트의 요청을 처리합니다.
  • Netty는 논블로킹 방식으로 동작하여 클라이언트의 요청을 처리하는 동안 다른 작업을 병렬로 수행할 수 있습니다.