비동기헷갈림정리 : 메시징 vs 리액티브

러브굿·2025년 10월 16일

비동기의 두 얼굴: 메시징 vs 리액티브

비동기(Asynchronous)라는 단어는 Kafka, Redis, WebFlux, Reactor 등 다양한 곳에서 자주 등장한다.
하지만 문맥마다 “비동기”의 의미는 다르다.
이 글에서는 메시징(Messageing)리액티브(Reactive) 가 말하는 비동기가 무엇이 다른지, 그리고 왜 구분해야 하는지를 명확히 정리한다.


1. 비동기의 층위부터 이해하기

구분메시징 시스템 (Kafka, Redis)Spring WebFlux / Reactor
비동기 의미시스템 간 통신 비동기쓰레드 단위의 논리 비동기
적용 범위서비스 ↔ 서비스 (네트워크 간)애플리케이션 내부 코드 흐름
대표 키워드Producer / Consumer / BrokerMono / Flux / Publisher / Subscriber
목적서비스 간 결합도 낮추기, 이벤트 지연 제거논블로킹, 고동시성, 리소스 효율

즉,

  • 메시징의 비동기는 “서비스 간의 시간차 통신”,
  • 리액티브의 비동기는 “코드 내부의 논리적 비동기 흐름”을 뜻한다.

2. 메시징의 비동기: 시스템 간 통신

Kafka나 Redis 같은 메시징 시스템은 여러 서비스 간 데이터를 주고받을 때 사용된다.
핵심은 “보내는 쪽은 즉시 응답을 기다리지 않는다”는 것이다.

[전략 서버] → [Kafka Broker] → [거래 서버]
  • Producer는 메시지를 발행하고 끝난다.
  • Consumer는 나중에 그 메시지를 읽는다.
  • Kafka가 두 시스템 사이의 비동기 버퍼 역할을 수행한다.

이 구조의 장점은 다음과 같다.

  • 서비스 간 결합도(의존성) 감소
  • 장애나 지연 발생 시 메시지 유실 방지 (큐잉)
  • 비동기 처리로 시스템 전체 응답 속도 향상

메시지(Message) 는 이 과정의 데이터 단위다.
예를 들어 다음 JSON 한 건이 메시지 한 단위다.

{
  "symbol": "BTCUSDT",
  "price": 67520.5,
  "timestamp": 1710241200,
  "signal": "BUY"
}

Kafka나 Redis는 이런 메시지를 큐 형태로 저장하고,
다른 서비스가 구독(Subscribe)하여 처리한다.


3. WebFlux의 비동기: 논리적 흐름

Spring WebFlux의 비동기란
하나의 서버 내부에서 요청을 처리할 때 쓰레드가 블로킹되지 않는 구조를 말한다.

예시:

@GetMapping("/price")
public Mono<PriceDto> getPrice() {
    return webClient.get()
            .uri("https://api.binance.com/price")
            .retrieve()
            .bodyToMono(PriceDto.class);
}

여기서 WebClient는 요청을 보낸 뒤 응답을 기다리지 않는다.
응답이 도착하면 그 시점에 Mono 체인이 이어서 실행된다.

즉,

  • CPU 쓰레드는 다른 요청을 처리할 수 있고,
  • 결과가 준비되면 콜백처럼 “반응(react)”한다.

이것이 리액티브 프로그래밍의 핵심, 즉 “데이터 스트림에 반응하는” 비동기이다.


4. 리액티브 프로그래밍의 특징

특징설명
Non-blockingI/O 작업 중 쓰레드가 대기하지 않음
Event-driven데이터가 도착하면 콜백 체인으로 자동 처리
Stream 기반Mono(단일 데이터), Flux(다중 데이터) 형태
Backpressure소비자가 감당할 만큼만 데이터 수신

예시:

Flux.fromIterable(List.of("BTC", "ETH", "XRP"))
    .flatMap(symbol -> webClient.get()
        .uri("/price?symbol=" + symbol)
        .retrieve()
        .bodyToMono(PriceDto.class))
    .subscribe(price -> System.out.println("가격 수신: " + price));

이 코드는 여러 API를 비동기적으로 동시에 호출하고,
각 응답이 올 때마다 순서에 상관없이 스트림처럼 처리한다.


5. 두 비동기의 본질적 차이

구분메시징 비동기리액티브 비동기
동작 영역네트워크 / 시스템 간애플리케이션 내부
단위MessageMono / Flux
시간 축서비스 간 지연 허용코드 실행 흐름 제어
목적서비스 decoupling쓰레드 효율, 응답성 향상
예시Kafka, Redis Pub/SubWebFlux, Reactor

즉,

  • 메시징은 시스템 간 데이터를 늦게 주고받는 구조,
  • 리액티브는 하나의 애플리케이션 내부에서 논블로킹으로 처리하는 구조다.

6. 예시로 보는 차이점

메시징 비동기 (Kafka)

// 메시지 발행 (비동기 전송)
kafkaTemplate.send("order.topic", orderEvent);

→ 메시지를 보내고 즉시 반환됨.
Consumer가 나중에 처리한다.


WebFlux 비동기 (리액티브 체인)

return webClient.get()
        .uri("/api/price")
        .retrieve()
        .bodyToMono(PriceDto.class)
        .map(price -> price.calculateFee());

→ I/O 대기 없이 다른 요청도 병렬로 처리 가능.
응답이 오면 Reactor가 map 체인을 실행한다.


7. 비유로 이해하기

관점메시징 비동기리액티브 비동기
비유택배 배송 시스템공장 내 컨베이어벨트
설명발신자는 물건 보내고 끝 (나중에 배송됨)물건이 컨베이어를 타고 올 때마다 기계가 반응
처리 주체여러 서버 간하나의 서버 내부

8. 정리

  • 메시징 비동기
    → 시스템 간 통신 단위.
    → Kafka, Redis, RabbitMQ 같은 메시지 브로커 중심.
    → “데이터를 보내놓고 나중에 처리”하는 구조.

  • 리액티브 비동기
    → 코드 실행 단위.
    → Spring WebFlux, Reactor 기반.
    → “데이터가 도착할 때마다 반응”하는 구조.

Kafka는 네트워크 레벨의 비동기,
WebFlux는 애플리케이션 내부의 논리 비동기라고 생각하면 된다.


9. 마무리

비동기라는 단어는 하나지만,
Kafka에서의 비동기와 WebFlux의 비동기는 전혀 다른 세계의 개념이다.

  • 메시징 비동기 → 서비스 간 시간차 처리
  • 리액티브 비동기 → 논블로킹 데이터 흐름

이 둘은 상호 대체 관계가 아니라, 서로 보완 관계다.
실무에서는 Kafka로 외부 이벤트를 비동기 전달하고,
내부에서는 WebFlux로 효율적으로 처리하는 식으로 함께 사용된다.


참고 자료

profile
마라토너형 개발자

0개의 댓글