본문 바로가기
Study/Spring

Spring WebFlux 이해하기: 리액티브 프로그래밍의 시작

by 코드콩 2025. 1. 16.
728x90
반응형

최근 마이크로서비스 아키텍처와 대용량 트래픽 처리에 대한 관심이 높아지면서, Spring WebFlux가 주목받고 있습니다. 전통적인 Spring MVC와는 다른 접근 방식을 제공하는 Spring WebFlux, 과연 어떤 특징을 가지고 있을까요?

Spring WebFlux란?

Spring WebFlux는 Spring Framework 5에서 새롭게 추가된 리액티브 웹 프레임워크입니다. 기존의 서블릿 기반 Spring MVC와는 달리, 비동기-논블로킹 방식으로 동작하며 Reactive Streams API를 기반으로 합니다.

주요 특징

1. 비동기-논블로킹 처리

  • 적은 수의 스레드로 많은 요청을 처리
  • 이벤트 루프 기반의 처리 방식
  • 백프레셔(Backpressure) 지원

2. 함수형 프로그래밍 스타일

  • 선언적 프로그래밍 방식 지원
  • Router Function을 통한 함수형 엔드포인트 정의
  • Mono와 Flux를 통한 데이터 스트림 처리

WebFlux 프로젝트 설정하기

Gradle 빌드 설정 (build.gradle)

plugins {
    id 'org.springframework.boot' version '3.2.2'
    id 'io.spring.dependency-management' version '1.1.4'
    id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

repositories {
    mavenCentral()
}

dependencies {
    // Spring WebFlux
    implementation 'org.springframework.boot:spring-boot-starter-webflux'

    // Reactor Test
    testImplementation 'io.projectreactor:reactor-test'

    // Spring Boot Test
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

    // Optional: R2DBC for reactive database access
    // implementation 'org.springframework.boot:spring-boot-starter-data-r2dbc'
    // implementation 'io.r2dbc:r2dbc-h2'
}

test {
    useJUnitPlatform()
}

settings.gradle

rootProject.name = 'webflux-demo'

애플리케이션 설정 (application.yml)

spring:
  webflux:
    base-path: /api

  # Reactor Netty 설정
  reactor:
    netty:
      ioWorkerCount: 4
      pool:
        maxConnections: 200
728x90
반응형

간단한 예제로 보는 Spring WebFlux

@RestController
public class UserController {
    private final UserRepository userRepository;

    public UserController(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @GetMapping("/users")
    public Flux<User> getAllUsers() {
        return userRepository.findAll();
    }

    @GetMapping("/users/{id}")
    public Mono<User> getUser(@PathVariable Long id) {
        return userRepository.findById(id);
    }

    @PostMapping("/users")
    public Mono<User> createUser(@RequestBody User user) {
        return userRepository.save(user);
    }
}

WebClient 설정

  • responseTimeout: 전체 요청-응답 사이클의 타임아웃을 설정. 서버로부터 첫 응답을 받기 시작해서 모든 응답을 받을 때까지의 최대 허용 시간
  • ReadTimeoutHandler: 서버로부터 데이터를 읽는 작업의 타임아웃
  • WriteTimeoutHandler: 서버로 데이터를 쓰는 작업의 타임아웃
@Configuration
public class WebClientConfig {
    @Bean
    public WebClient webClient() {
        return WebClient.builder()
            .clientConnector(new ReactorClientHttpConnector(
                HttpClient.create()
                    .responseTimeout(Duration.ofSeconds(5)) // 전체 응답 타임아웃
                    .doOnConnected(conn -> conn
                        .addHandlerLast(new ReadTimeoutHandler(5)) // 읽기 타임아웃
                        .addHandlerLast(new WriteTimeoutHandler(5))) // 쓰기 타임아웃
            ))
            .build();
    }
}

테스트 작성하기

@SpringBootTest
@AutoConfigureWebTestClient
class UserControllerTest {
    @Autowired
    private WebTestClient webTestClient;

    @Test
    void getAllUsers() {
        webTestClient.get()
            .uri("/users")
            .exchange()
            .expectStatus().isOk()
            .expectBodyList(User.class)
            .hasSize(3);
    }
}

운영 환경 설정

logback-spring.xml 설정

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="CONSOLE"/>
    </root>

    <!-- Reactor Debug 로깅 -->
    <logger name="reactor.netty" level="DEBUG"/>
</configuration>

마치며

Spring WebFlux는 현대적인 웹 애플리케이션 개발에 있어 강력한 도구입니다. Gradle을 사용한 프로젝트 설정부터 운영 환경 설정까지 살펴보았습니다. 프로젝트의 요구사항과 팀의 역량을 고려하여 도입을 결정하시기 바랍니다.

참고 자료

  • Spring 공식 문서
  • Reactive Streams 스펙
  • Project Reactor 문서
  • Gradle 공식 문서
728x90
반응형