본문 바로가기
[개발] 프레임워크/Spring

WebFlux

by Devsong26 2023. 10. 22.

WebFlux는 Spring Framework 5에서 도입된 반응형 프로그래밍 모델을 위한 웹 프레임워크입니다. WebFlux는 전통적인 Spring MVC와는 다르게, 비동기 및 반응형 웹 애플리케이션을 만들기 위해 설계되었습니다. WebFlux의 주요 특징과 이점은 다음과 같습니다:

1. 비동기 및 반응형: WebFlux는 비동기 및 반응형 웹 애플리케이션 개발을 지원합니다. 이를 통해 대량의 동시 요청을 효율적으로 처리할 수 있습니다.

2. Reactor 프레임워크: WebFlux는 Reactor 프레임워크를 기반으로 합니다. Reactor는 `Mono`와 `Flux`라는 반응형 타입을 제공하며, 이를 통해 데이터 스트림을 비동기적으로 처리할 수 있습니다.

3. 어노테이션 기반과 함수형 스타일 모두 지원: WebFlux는 전통적인 어노테이션 기반의 프로그래밍 모델뿐만 아니라, 라우터와 핸들러를 사용하는 함수형 스타일의 프로그래밍 모델도 지원합니다.

4. 효율적인 리소스 활용: WebFlux는 Netty와 같은 비동기 런타임에서 실행될 때, 스레드와 기타 리소스를 효율적으로 활용할 수 있습니다. 따라서 동기 블로킹 방식보다 적은 수의 스레드로 더 많은 동시 연결을 처리할 수 있습니다.

5. 다양한 데이터 소스 지원: WebFlux는 전통적인 데이터베이스 뿐만 아니라, 비동기 데이터베이스 드라이버와의 통합도 지원합니다.

6. 서버와 클라이언트 모델: WebFlux는 반응형 웹 애플리케이션을 개발할 수 있는 서버 측 컴포넌트뿐만 아니라, `WebClient`라는 비동기, 반응형 웹 클라이언트도 제공합니다.

요약하면, WebFlux는 대량의 동시 요청과 데이터 스트림을 효율적으로 처리하기 위해 설계된 Spring의 비동기, 반응형 웹 프레임워크입니다.

 

 

 

 

클라이언트가 서버와 통신할 때 상황

 

API 호출자의 관점에서 보면, 리액티브 스트림이 결과를 반환하기 전까지 기다리게 되는 것은 일반적인 동기 API 호출과 크게 다르지 않습니다. 즉, 호출자는 응답을 받을 때까지 기다려야 합니다.

그러나 서버의 관점에서는 상황이 다릅니다:

전통적인 동기 방식: 클라이언트가 API 요청을 보내면, 서버는 처리가 완료될 때까지 해당 스레드가 블로킹됩니다. 따라서 동시에 많은 요청이 오면 스레드 풀의 리소스가 고갈될 위험이 있습니다.

리액티브 방식: 클라이언트가 API 요청을 보내면, 서버는 해당 작업을 비동기적으로 처리하며, 작업 중에는 스레드가 블로킹되지 않습니다. 따라서 동일한 스레드가 다른 작업을 동시에 처리할 수 있으며, 스레드 풀의 리소스를 효율적으로 활용할 수 있습니다.

결론적으로, 클라이언트의 관점에서는 리액티브 API의 응답을 기다리는 것이 동기 API의 응답을 기다리는 것과 크게 다르지 않을 수 있습니다. 하지만 서버 측에서는 리액티브 방식이 리소스 활용 측면에서 훨씬 효율적입니다.

또한 리액티브 프로그래밍은 데이터 스트림의 반응성을 향상시키기 위한 것이기도 합니다. 즉, 큰 데이터셋을 전송할 때 클라이언트가 모든 데이터를 한 번에 받기를 기다릴 필요 없이, 데이터가 사용 가능하게 되자마자 점진적으로 받을 수 있습니다.

/*
    StepVerfier는 비동기 프로듀서의 일련의 과정이 종료될 때까지 기다렸다가 결과를 평가합니다.
    
    해당 테스트 결과는 delayElement 설정으로 인해 3Sec xxx ms의 소요시간을 갖습니다.
*/

public class WebFluxTest {

    @Test
    public void test() {
        StepVerifier.create(getMono())
                .expectNext("TEST-MONO-String")
                .verifyComplete();
    }

    private Mono<String> getMono(){
        return Mono.just("TEST-MONO-String")
                .delayElement(Duration.ofSeconds(3));
    }

}

 


 

 

R2DBC

R2DBC (Reactive Relational Database Connectivity)는 관계형 데이터베이스와의 연결을 위한 리액티브 프로그래밍 모델을 지원하는 API입니다. R2DBC는 전통적인 블로킹 방식인 JDBC와 대조되는 논블로킹 방식을 제공합니다. 

R2DBC의 주요 특징 및 포인트는 다음과 같습니다:

1. 논블로킹: R2DBC는 논블로킹 연산을 기본으로 합니다. 따라서 데이터베이스 I/O 작업 중에도 스레드가 블로킹되지 않습니다.

2. 리액티브 스트림 지원: R2DBC는 [Project Reactor](https://projectreactor.io/)의 `Mono`와 `Flux` 리액티브 타입을 사용하여 데이터를 반환합니다. 이를 통해 데이터베이스에서 데이터를 조회하거나 변경할 때 리액티브 프로그래밍 패러다임을 사용할 수 있습니다.

3. 다양한 데이터베이스 드라이버: R2DBC는 다양한 관계형 데이터베이스를 지원하기 위한 드라이버를 제공합니다. 예를 들어 PostgreSQL, MySQL, H2, Microsoft SQL Server 등에 대한 R2DBC 드라이버가 있습니다.

4. Spring Data R2DBC: Spring Data 프로젝트는 R2DBC를 지원하기 위한 모듈을 제공합니다. 이를 통해 Spring Data의 리포지토리 패턴을 사용하여 R2DBC 연산을 쉽게 수행할 수 있습니다.

5. 비동기 & 백프레셔: R2DBC는 리액티브 스트림의 백프레셔(backpressure) 개념을 지원합니다. 이를 통해 데이터베이스와의 통신에서 발생할 수 있는 리소스의 과다 사용 문제를 해결할 수 있습니다.

6. 최적화된 리소스 활용: 논블로킹 방식의 특성상, 스레드 풀의 스레드를 효율적으로 활용하여 동시에 많은 요청을 처리할 수 있습니다.

요약하면, R2DBC는 리액티브 프로그래밍 모델을 사용하여 관계형 데이터베이스와의 연결을 비동기적이고 논블로킹 방식으로 처리할 수 있도록 설계된 API입니다. 이를 통해 스케일링 문제와 고성능을 요구하는 애플리케이션에서의 데이터베이스 액세스를 최적화할 수 있습니다.

 

 

 

 

R2DBC와 WebFlux

R2DBC (Reactive Relational Database Connectivity)는 관계형 데이터베이스와의 연결을 위한 리액티브 프로그래밍 모델을 제공하는 API입니다. 전통적인 JDBC는 블로킹 방식으로 작동하는 반면, R2DBC는 논블로킹 방식으로 작동합니다.

Spring WebFlux와 R2DBC의 관계 및 연관점을 살펴보겠습니다:

리액티브 프로그래밍 모델: Spring WebFlux는 웹 계층에서 리액티브 프로그래밍을 지원합니다. 반면, R2DBC는 데이터 액세스 계층에서 리액티브 프로그래밍을 지원합니다. 이 두 기술을 함께 사용하면, 웹 요청 처리부터 데이터베이스 액세스까지 전체 스택에서 논블로킹 및 리액티브 방식으로 작동할 수 있습니다.

효율성: WebFlux와 R2DBC를 함께 사용하면, 데이터베이스 I/O 작업이 진행되는 동안 스레드가 블로킹되지 않아, 스레드의 효율적인 활용이 가능합니다. 이로 인해 더 많은 동시 요청을 처리할 수 있습니다.

통합: Spring Data R2DBC는 Spring Data 프로젝트의 일부로서, 리액티브 CRUD 연산을 지원하는 리포지토리를 제공합니다. 이를 통해 WebFlux 애플리케이션에서 R2DBC 연결을 쉽게 통합할 수 있습니다.

 

 


 

 

ReactiveMongoRepository

`ReactiveMongoRepository`는 Spring Data MongoDB 프로젝트에서 제공하는 인터페이스로, MongoDB와의 리액티브 프로그래밍 방식을 사용한 데이터 액세스를 지원합니다. 이 인터페이스는 주로 CRUD (생성, 조회, 수정, 삭제) 연산을 비동기적으로 수행하기 위한 메서드들을 제공하며, MongoDB 데이터베이스와의 통신을 논블로킹 방식으로 처리할 수 있게 도와줍니다.

`ReactiveMongoRepository`의 주요 특징은 다음과 같습니다:

1. 논블로킹 CRUD 연산: `ReactiveMongoRepository`는 MongoDB에 대한 기본적인 CRUD 연산을 수행하기 위한 여러 메서드를 포함하고 있습니다. 이러한 메서드들은 `Mono`와 `Flux`와 같은 리액티브 타입을 반환하며, 이를 통해 논블로킹 연산이 가능합니다.

2. Reactive Streams 지원: 이 인터페이스는 Project Reactor의 리액티브 타입인 `Mono`와 `Flux`를 사용하여 연산 결과를 반환합니다. 이를 통해 연속적인 데이터 스트림 처리와 백프레셔 지원이 가능합니다.

3. 간단한 쿼리 메서드: `ReactiveMongoRepository`를 확장하여 사용자 정의 인터페이스를 생성할 때, 메서드 이름에 따라 자동으로 쿼리를 생성하는 기능을 제공합니다. 예를 들어, `findByUsername`와 같은 메서드 이름을 사용하면, username 필드를 기준으로 조회하는 쿼리가 자동으로 생성됩니다.

4. 커스텀 쿼리 지원: 필요한 경우, `@Query` 어노테이션을 사용하여 MongoDB 쿼리를 직접 작성하고 해당 쿼리를 수행하는 리액티브 메서드를 정의할 수 있습니다.

간단한 예제:

public interface UserRepository extends ReactiveMongoRepository<User, String> {

    Flux<User> findByLastName(String lastName);

    @Query("{ 'firstName': ?0 }")
    Mono<User> findByFirstNameCustom(String firstName);
}


이 예제에서 `UserRepository`는 `ReactiveMongoRepository`를 확장하고 있으며, `findByLastName` 메서드는 lastName 필드를 기준으로 사용자들을 조회하는 리액티브 메서드입니다. 또한, `findByFirstNameCustom` 메서드는 커스텀 쿼리를 사용하여 firstName 필드를 기준으로 사용자를 조회합니다.

결론적으로, `ReactiveMongoRepository`는 MongoDB와의 리액티브 프로그래밍 방식을 사용한 데이터 액세스를 간편하게 수행할 수 있도록 지원하는 Spring Data MongoDB의 주요 인터페이스입니다.