[WebFlux] 리액티브 프로그래밍을 활용한 비동기 데이터 처리

궁금하면 500원·2024년 11월 6일

미생의 스프링

목록 보기
23/48

1. Spring WebFlux와 리액티브 프로그래밍

Spring WebFlux는 Spring에서 제공하는 리액티브 프로그래밍 지원 프레임워크입니다.

이는 리액티브 스트림 표준을 구현한 리액터(Reactor) 라이브러리를 기반으로 하며, 비동기적이고

논블로킹(non-blocking) 방식으로 요청을 처리하는 애플리케이션을 개발할 수 있게 합니다.

기존의 동기적인 방식에서 벗어나, 더 효율적이고 확장성이 뛰어난 시스템을 개발할 수 있습니다.

  • 요청-응답 패턴의 비동기화: 클라이언트는 서버에 요청을 보내고, 그 응답을 기다리지 않고 다른 작업을 할 수 있습니다.
    서버는 데이터를 준비하는 대로 응답을 지속적으로 보냅니다.

  • 스트리밍: 데이터가 도착하는 즉시 클라이언트에게 전달되는 방식입니다.
    예를 들어, SSE(Server-Sent Events) 프로토콜을 활용하여 실시간으로 데이터를 스트리밍할 수 있습니다.

2. 리액티브 스트림을 활용한 Spring WebFlux 예제

Spring WebFlux의 주요 특징은 Flux와 Mono라는 두 가지 리액티브 타입을 통해 비동기 데이터를 처리할 수 있다는 점입니다.

  • Mono: 단 하나의 값을 반환하는 비동기 스트림.
  • Flux: 여러 값을 반환하는 비동기 스트림.

Mono 예제 (단일 응답)

@GetMapping("/hello")
public Mono<String> sayHello() {
    return Mono.just("Hello, World!");  // 단일 값을 반환
}

Flux 예제 (여러 값 반환)

@GetMapping("/numbers")
public Flux<Integer> getNumbers() {
    return Flux.range(1, 5);  // 1부터 5까지의 숫자 스트림
}

3. WebFlux에서 비동기 처리와 서버 간 스트리밍

SSE(Server-Sent Events)는 서버에서 클라이언트로 지속적으로 데이터를 전송하는 기술입니다. 클라이언트가 SSE 엔드포인트에 요청을 보내면, 서버는 데이터를 지속적으로 스트리밍합니다.

SSE 예제 코드

@GetMapping("/events")
public Flux<ServerSentEvent<String>> getEvents() {
    return Flux.interval(Duration.ofSeconds(1))
               .map(seq -> ServerSentEvent.builder("Event #" + seq)
                                          .build());
}

위 코드에서 Flux.interval()은 1초 간격으로 이벤트를 발생시키고, 이를 클라이언트에 실시간으로 전송합니다.

4. 비동기 DB 연동: R2DBC

리액티브 프로그래밍을 통해 DB 연동 또한 비동기적으로 처리할 수 있습니다.

R2DBC는 리액티브 SQL 데이터베이스 커넥터로, 기존의 JDBC 방식이 동기적인 반면, R2DBC는 비동기적으로 데이터를 처리할 수 있습니다.

R2DBC 사용 예제

1. 의존성 추가 (pom.xml)

<dependency>
    <groupId>io.r2dbc</groupId>
    <artifactId>r2dbc-h2</artifactId>
</dependency>

2. Database Configuration

@Configuration
public class DatabaseConfig {

    @Bean
    public ConnectionFactory connectionFactory() {
        return new PostgresqlConnectionFactory(
                PostgresqlConnectionConfiguration.builder()
                        .host("localhost")
                        .database("test")
                        .username("user")
                        .password("password")
                        .build());
    }
}

3. Service에서 비동기 DB 쿼리

@Service
public class UserService {

    private final DatabaseClient databaseClient;

    public UserService(DatabaseClient databaseClient) {
        this.databaseClient = databaseClient;
    }

    public Flux<User> getAllUsers() {
        return databaseClient.select()
                              .from(User.class)
                              .fetch()
                              .all();  // 비동기적으로 데이터 조회
    }
}

결론

리액티브 프로그래밍을 이용한 Spring WebFlux는 비동기적인 스트리밍 방식으로 요청과 응답을 처리하여, 전통적인 동기식 애플리케이션에 비해 훨씬 효율적이고 확장성 높은 시스템을 만들 수 있게 해줍니다.
특히 Flux와 Mono를 통해 비동기 데이터 스트림을 쉽게 다룰 수 있고, R2DBC를 이용하면 DB도 비동기적으로 처리할 수 있습니다.
서버 간 실시간 데이터 스트리밍을 구현할 때는 SSE를 활용하여 클라이언트와 서버 간 지속적인 데이터 통신을 구현할 수 있습니다.

profile
에러가 나도 괜찮아 — 그건 내가 배우고 있다는 증거야.

0개의 댓글