Synchronous 🆚 Asynchronous | RabbitMQ 기반 비동기 처리 구조

2025. 6. 5. 18:34·TIL (Today I Learned)

⏱️ 동기와 비동기

동기(Synchronous)

  • 한 작업이 완료될 때까지 대기한 후 다음 작업을 수행하는 방식
  • 하나의 요청이 끝나기 전까지 다음 처리를 하지 못합니다.
    • 특정 작업이 오래 걸릴 경우 다른 작업이 블로킹(Blocking) 됨
  • 순차적으로 실행되므로 코드의 실행 흐름을 예측하기 쉽지만, 속도가 느릴 수 있음

 

비동기(Asynchronous)

  • 한 작업을 실행하는 동안 다른 작업을 동시에 수행하는 방식 (대기하지 않음)
  • 요청을 보낸 뒤 응답을 기다리지 않고 바로 다음 작업을 진행
  • 시간이 오래 걸리는 작업(예: API 호출, 데이터베이스 조회, 파일 처리)을 비동기로 처리하면 성능이 향상됨

 

비교

  동기 비동기
작업 처리 방식 순차적으로 실행 동시에 여러 작업 가능
응답 대기 여부 요청이 끝날 때까지 대기 결과를 기다리지 않고 즉시 다음 코드 실행
성능 속도가 상대적으로 느림 대규모 트래픽에서 성능 향상
사용 방식 일반 메서드 호출 Java의 경우 `@Async`, `CompletableFuture`, `ExecutorService`, `Reactor`(`WebFlux`) 등을 이용하여 비동기 처리
사용 예시 - 작업의 순서가 중요할 때
- 각 단계의 결과가 다음 단계에 즉시 필요할 때
- 간단한 스크립트나 작은 규모의 프로그램
- 네트워크 요청이나 파일 I/O와 같은 시간이 오래 걸리는 작업을 처리할 때
- 여러 독립적인 작업을 동시에 처리해야 할 때
- 사용자 인터페이스의 반응성을 유지해야 할 때
- 대규모 동시성이 필요한 서버 애플리케이션

 


📦 RabbitMQ를 활용한 비동기 처리 구조

Java 내부 비동기(`@Async` 등)과 RabbitMQ 비교

  Java 내부 비동기
(`@Async`, `CompletableFuture` 등)
메시지 큐 기반 비동기 (RabbitMQ)
작업 실행 위치 JVM 내부 스레드 (동일 프로세스) 외부 브로커(RabbitMQ)를 통해 별도 Consumer 프로세스
비동기 트리거 코드 상에서 메서드를 직접 비동기로 실행 메시지를 큐에 publish 후, 리스너가 비동기 처리
목적 주로 단기적 비동기 작업 (ex. 병렬 처리) 시스템 간 비동기 통신 및 이벤트 처리
결과 처리 방식 반환값으로 `CompletableFuture` 등 활용 메시지 처리 후 후속 로직 또는 저장 (보통 리턴 없음)
내결함성 JVM 내 예외 발생 시 앱에 영향  DLQ, 재시도, 큐 모니터링 등으로 높은 복원력 확보 가능
확장성 스레드풀/리액터 기반 확장 MQ 수평 확장으로 고성능 처리 가능
(멀티 인스턴스 대응)
정리 @Async, CompletableFuture 등은 애플리케이션 내부 병렬성 향상 도구 RabbitMQ는 서비스 간 비동기 메시지 전달 및 아키텍처 구성 도구

 

구성 요소

  • Producer: 메시지를 Queue에 전송하는 주체
  • Queue: 메시지를 임시로 저장하고, Consumer가 가져가길 기다림
  • Consumer: Queue로부터 메시지를 수신하고 처리
  • Exchange: 메시지를 받아서 라우팅 규칙에 따라 적절한 Queue로 전달

 

🔔 실제 구현 예시: 채팅 알림 비동기 처리

`table-now` 프로젝트에서는 RabbitMQ를 통해 채팅 알림, 예약 리마인드, 이벤트 알림 등을 메시지 큐 기반 비동기 처리했습니다.

 

1. 채팅 메시지 전송

rabbitTemplate.convertAndSend(
        CHAT_EXCHANGE,
        CHAT_ROUTING_KEY,
        response
);

→ 사용자가 채팅 메시지를 보내면 서버는 메시지를 큐에 넣고, 즉시 응답을 반환
→ 이후 실제 알림 전송은 별도의 Consumer가 처리

 

2. 메시지 수신 및 알림 생성

@RabbitListener(queues = CHAT_QUEUE)
public void consume(ChatMessageResponse chatMessage) {
    // 생략
    try {
        notificationService.createNotification(
                NotificationRequestDto.builder()
                        .userId(receiverId)
                        .type(NotificationType.CHAT)
                        .content(buildChatContent(chatMessage))
                        .build()
        );
    // 생략
    } catch (Exception e) {
        // 생략
    }
}
  • 수신자는 `@RabbitListener`를 통해 큐에 쌓인 메시지를 처리
  • (이 구조로 실제 알림 생성이 느려도 사용자 응답에는 영향이 없다.)

 

3. 실패 대응: DLQ + 재시도 처리

throw new AmqpRejectAndDontRequeueException("[DLQ] 알림 전송 실패 → DLQ로 이동", e);
  • 메시지 처리 실패 시 Dead Letter Queue(DLQ)로 이동
  • DLQ에서는 Retry Count를 기준으로 최대 3회까지 재시도 (x-retry-count)

→ 유실 없는 메시지 처리 구조

 

 

https://github.com/spring-team-7/table-now/pull/199/commits/c7f8eff16f1f17ae42145cb9306198c2c274cd40

 

[feat] WebSocket + RabbitMQ 기반 채팅 기능 고도화 by mannaKim · Pull Request #199 · spring-team-7/table-now

🔗 Issue Number close #189 📝 작업 내역 Spring WebSocket + STOMP 메시지 Relay를 RabbitMQ로 전환 이전 구조 (SimpleBroker)에서는 → 서버(Spring)가 직접 클라이언트에게 메시지를 브로드캐스트 지금 구조 (StompBrok

github.com

https://github.com/spring-team-7/table-now/pull/268

 

[feat] 채팅 알림 DLQ / DLX 적용 by mannaKim · Pull Request #268 · spring-team-7/table-now

🔗 Issue Number close #257 📝 작업 내역 RabbitConstant에 CHAT_DLX, CHAT_DLQ 상수 추가 RabbitConfig에 chat DLX, DLQ, 바인딩 설정 추가 ChatDlqReprocessor 클래스 생성 ChatRetryService 클래스 생성 및 재처리 로직 구현 💡

github.com

 


📝 비동기 처리 방식 정리

상황 추천 방식
단순한 비동기 작업 (ex. 비동기 메일 전송) @Async, CompletableFuture
사용자 응답과 무관한 처리 RabbitMQ
재시도/지연 처리 필요 RabbitMQ + Retry Queue

 

RabbitMQ를 활용한 비동기 이벤트 처리 구조는 다음과 같은 장점을 가진다:

  • 사용자 응답 속도 향상
  • 처리 실패에 대한 유연한 대응 (DLQ, Retry)

 

저작자표시 비영리 변경금지 (새창열림)

'TIL (Today I Learned)' 카테고리의 다른 글

Spring Boot 면접 대비 개념 정리❕  (1) 2025.06.19
JVM의 개념과 내부 구조 정리  (3) 2025.06.19
JWT 인증 기반 WebSocket 연결 실패, 원인과 해결법  (2) 2025.06.05
Spring Boot 설정값 바인딩 정리: @Value vs @ConfigurationProperties  (2) 2025.05.24
동시성 제어는 어떻게 할까❓  (0) 2025.03.26
'TIL (Today I Learned)' 카테고리의 다른 글
  • Spring Boot 면접 대비 개념 정리❕
  • JVM의 개념과 내부 구조 정리
  • JWT 인증 기반 WebSocket 연결 실패, 원인과 해결법
  • Spring Boot 설정값 바인딩 정리: @Value vs @ConfigurationProperties
기만나🐸
기만나🐸
공부한 내용을 기록합시다 🔥🔥🔥
  • 기만나🐸
    기만나의 공부 기록 🤓
    기만나🐸
  • 전체
    오늘
    어제
    • ALL (147)
      • TIL (Today I Learned) (56)
      • Dev Projects (15)
      • Algorithm Solving (67)
        • Java (52)
        • SQL (15)
      • Certifications (8)
        • 정보처리기사 실기 (8)
  • 인기 글

  • 태그

    Google Fonts
    jwt
    BOJ
    jQuery
    백준
    sql
    Subquery
    bootstrap
    GROUP BY
    programmers
    다이나믹프로그래밍
    Firebase
    완전탐색
    javascript
    HTML
    dp
    greedy
    java
    BFS
    그리디
    프로그래머스
    시뮬레이션
    join
    CSS
    백트래킹
    mysql
    자료구조
    DFS
    jpa
    websocket
  • 최근 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
기만나🐸
Synchronous 🆚 Asynchronous | RabbitMQ 기반 비동기 처리 구조
상단으로

티스토리툴바