IT기술/webflux (reactor)

Blocking I/O와 Non-Blocking I/O: 개념과 WebFlux에서의 활용

후스파 2025. 3. 23. 00:23
반응형
spring framework webflux reactor

Blocking I/O와 Non-Blocking I/O는 시스템의 성능과 효율성을 결정짓는 중요한 개념입니다. 특히, Spring WebFlux는 Non-Blocking I/O를 기반으로 설계되어 대량의 요청을 효율적으로 처리할 수 있도록 돕습니다. 이 글에서는 두 방식의 차이점과 활용 방안을 살펴보겠습니다.

1. Blocking I/O란?

Blocking I/O는 요청 스레드가 I/O 작업이 완료될 때까지 대기하는 방식입니다. 이는 간단하고 직관적이지만, 대량의 요청을 처리할 때 다음과 같은 문제를 야기합니다:

  • 스레드 대기: 하나의 요청이 완료될 때까지 다른 요청은 대기 상태에 놓입니다.
  • 컨텍스트 스위칭 비용: 다수의 스레드가 생성되면, CPU가 작업 전환에 많은 시간을 소비하게 됩니다.
  • 자원 낭비: 유휴 상태의 스레드가 많아지면서 메모리와 CPU 자원이 비효율적으로 사용됩니다.

코드 예제: Blocking I/O

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BlockingIOExample {
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 3; i++) {
            readFile();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("총 소요 시간: " + (endTime - startTime) + "ms");
    }

    public static void readFile() {
        try (BufferedReader br = new BufferedReader(new FileReader("example.txt"))) {
            String line;
            while ((line = br.readLine()) != null) {
                // 파일 읽기 작업
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
 
 
 

특징: 파일 읽기가 순차적으로 진행되며, 모든 작업이 완료될 때까지 다른 요청은 대기합니다.

2. Non-Blocking I/O란?

Non-Blocking I/O는 I/O 작업 중에도 스레드가 차단되지 않고 다른 작업을 수행할 수 있는 방식입니다. 이는 적은 수의 스레드로도 많은 요청을 처리할 수 있어 효율적입니다.

주요 특징

  • 요청 스레드 차단 없음: 작업이 완료될 때까지 기다리지 않고 다른 작업을 처리합니다.
  • 효율적인 자원 사용: 적은 수의 스레드로도 높은 동시성을 지원합니다.
  • 전 과정 Non-Blocking: 모든 요소가 Non-Blocking으로 동작해야 최대 효과를 발휘합니다.

코드 예제: Non-Blocking I/O

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.concurrent.CompletableFuture;

public class NonBlockingIOExample {
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        CompletableFuture<Void> future1 = CompletableFuture.runAsync(NonBlockingIOExample::readFile);
        CompletableFuture<Void> future2 = CompletableFuture.runAsync(NonBlockingIOExample::readFile);
        CompletableFuture<Void> future3 = CompletableFuture.runAsync(NonBlockingIOExample::readFile);

        CompletableFuture<Void> allOf = CompletableFuture.allOf(future1, future2, future3);
        allOf.join(); // 모든 작업이 완료될 때까지 기다림

        long endTime = System.currentTimeMillis();
        System.out.println("총 소요 시간: " + (endTime - startTime) + "ms");
    }

    public static void readFile() {
        try {
            Files.lines(Paths.get("example.txt")).forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
 
 
 

특징: 비동기 처리를 통해 여러 파일 읽기 작업이 동시에 진행됩니다.

3. Spring WebFlux와 Non-Blocking I/O

Spring WebFlux는 Non-Blocking I/O를 기반으로 설계된 프레임워크로, 다음과 같은 상황에서 효과적입니다:

  1. 대량의 요청 트래픽 처리
    • 하나의 스레드로 다수의 요청을 처리하여 서버 자원을 효율적으로 활용합니다.
  2. 마이크로서비스 아키텍처
    • 서비스 간 비동기 통신을 통해 응답 속도를 향상시킵니다.
  3. 실시간 데이터 스트리밍
    • 지속적으로 데이터가 발생하는 환경에서 높은 성능을 제공합니다.

4. Non-Blocking I/O 도입 시 주의점

Non-Blocking I/O는 장점이 많지만, 다음과 같은 단점도 고려해야 합니다:

  1. 복잡한 코드 구조
    • 비동기 프로그래밍 패턴(콜백, 프라미스 등)은 코드 가독성을 떨어뜨릴 수 있습니다.
  2. 디버깅 어려움
    • 순차적이지 않은 실행 흐름으로 인해 오류 원인을 파악하기 어렵습니다.
  3. 기존 시스템과 호환성 문제
    • 기존 Blocking 기반 시스템에서 전환하려면 많은 리팩토링이 필요합니다.
  4. CPU 바운드 작업에서 성능 저하 가능성
    • CPU 중심 작업에서는 Non-Blocking 방식의 이점이 줄어듭니다.

결론

Blocking I/O와 Non-Blocking I/O는 각각의 장단점이 있으며, 시스템 요구사항에 따라 적합한 방식을 선택해야 합니다. Spring WebFlux와 같은 Non-Blocking 프레임워크는 특히 대량 요청 처리나 실시간 스트리밍 환경에서 큰 효과를 발휘합니다. 그러나 복잡한 코드 구조와 러닝 커브를 고려하여 도입 여부를 신중히 결정해야 합니다.

앞으로 고민할 점

  1. 기존 Blocking 기반 시스템을 어떻게 점진적으로 전환할 것인가?
  2. 비동기 프로그래밍 패턴에서 디버깅과 유지보수를 어떻게 개선할 것인가?
  3. CPU 바운드 작업과 혼합된 환경에서 최적화를 어떻게 이룰 것인가?

필요한 상황에 적합한 기술을 선택하는 것이 가장 중요한 전략입니다.

 

 

[WebFlux] Blocking I/O, Non-Blocking I/O

Blocking I/O 정의 Blocking I/O는 하나의 요청에 여러 스레드가 동작할 때, 특정 스레드가 I/O 작...

blog.naver.com

 

 

[WebFlux 심층 분석] 리액티브 스트림즈 컴포넌트 구현 및 Kafka와의 비교

리액티브 스트림즈는 비동기적이고 Non-Blocking 방식의 데이터 처리를 위한 표준입니다. 이 글에서는 리액티브 스트림즈의 주요 컴포넌트 구현과 Apache Kafka와의 차이점을 살펴보겠습니다. 리액티

hoosfa.tistory.com

 

반응형