TIL - 20251121

juni·2025년 11월 21일

TIL

목록 보기
184/316

1121 Spring Boot 비동기 처리 심화: 메시지 큐와 RabbitMQ


✅ 1. 비동기 처리의 한계와 메시지 큐의 필요성

  • 이전에 학습한 @Async는 간단한 비동기 처리를 가능하게 하지만, 몇 가지 한계점을 가집니다.

  • @Async의 한계:

    1. 애플리케이션 종속성: 비동기 작업이 애플리케이션 서버(WAS)의 내부 스레드 풀에서 동작하므로, 작업량이 많아지면 WAS 자체의 성능에 영향을 줄 수 있습니다.
    2. 데이터 유실 위험: 비동기 작업이 큐에 쌓여있을 때 애플리케이션이 갑자기 종료되면, 처리되지 않은 작업들은 유실됩니다.
    3. 확장성 문제: @Async는 다른 서버 인스턴스와 작업을 공유할 수 없어, MSA(Microservice Architecture)와 같은 분산 환경에서는 사용하기 어렵습니다.
  • 메시지 큐 (Message Queue, MQ): 이러한 문제들을 해결하기 위해, 애플리케이션 간에 메시지를 안정적으로 비동기 통신할 수 있도록 도와주는 별도의 미들웨어 시스템입니다.


✅ 2. 메시지 큐(MQ)의 핵심 개념

  • 메시지 큐는 "생산자-소비자(Producer-Consumer)" 패턴을 기반으로 동작합니다.
  1. 생산자 (Producer):

    • 메시지(처리해야 할 작업 데이터)를 생성하여 메시지 큐에 보내는(Publish) 주체입니다.
    • 메시지를 큐에 넣은 후, 그 작업이 언제 어떻게 처리되는지는 신경 쓰지 않고 즉시 자신의 다음 일을 계속합니다.
  2. 소비자 (Consumer):

    • 메시지 큐를 계속 지켜보고 있다가(Subscribe), 새로운 메시지가 들어오면 이를 가져와서(Consume) 처리하는 주체입니다.
  3. 메시지 큐 (Message Queue):

    • 생산자가 보낸 메시지를 임시로 저장하는 "우체통" 또는 "대기열" 역할을 합니다.
    • 생산자와 소비자는 서로를 전혀 알지 못하며, 오직 메시지 큐를 통해서만 상호작용합니다. 이를 느슨한 결합(Loose Coupling)이라고 합니다.

➕ 메시지 큐의 장점

  • 비동기성 (Asynchronicity): 생산자는 소비자의 작업 완료를 기다리지 않아, 시스템의 전체적인 응답성이 향상됩니다.
  • 안정성 및 데이터 보장: 메시지는 큐에 안전하게 저장되므로, 소비자가 처리 중 실패하거나 시스템이 다운되어도 메시지가 유실되지 않고 나중에 다시 처리될 수 있습니다.
  • 확장성 (Scalability): 작업량이 많아지면, 메시지를 처리하는 소비자의 수만 늘려서 전체 처리량을 쉽게 확장할 수 있습니다.
  • 탄력성 (Resilience): 소비 시스템 중 하나가 장애가 발생해도, 생산자는 계속해서 메시지를 큐에 보낼 수 있습니다. 장애가 복구되면 소비자는 큐에 쌓여있던 메시지를 처리하기 시작합니다.

✅ 3. RabbitMQ: AMQP 프로토콜 기반의 메시지 브로커

  • RabbitMQ는 가장 널리 사용되는 오픈소스 메시지 브로커(Message Broker) 중 하나입니다.
  • AMQP (Advanced Message Queuing Protocol)라는 표준 메시징 프로토콜을 구현하여, 서로 다른 언어나 플랫폼으로 만들어진 애플리케이션 간에도 안정적인 메시지 통신을 보장합니다.

➕ RabbitMQ의 주요 구성 요소

  1. Exchange: 생산자로부터 메시지를 가장 먼저 받는 곳. 우체국의 "접수 창구"와 같습니다. Exchange는 받은 메시지를 어떤 큐로 보낼지 결정하는 라우팅 규칙을 가지고 있습니다.
    • Direct Exchange: 라우팅 키가 정확히 일치하는 큐에만 메시지를 전달.
    • Topic Exchange: 라우팅 키가 특정 패턴에 맞는 큐에 메시지를 전달.
    • Fanout Exchange: 자신에게 바인딩된 모든 큐에 메시지를 브로드캐스트.
  2. Queue: Exchange로부터 전달받은 메시지를 소비자가 가져갈 때까지 저장하는 대기열.
  3. Binding: Exchange와 Queue를 연결하는 규칙. "이 Exchange는 이런 라우팅 키를 가진 메시지를 저 Queue로 보내라"고 정의합니다.

✅ 4. Spring AMQP를 이용한 RabbitMQ 연동

  • Spring AMQP는 Spring 애플리케이션에서 AMQP 기반의 메시지 브로커(특히 RabbitMQ)를 쉽게 사용할 수 있도록 도와주는 프로젝트입니다.

➕ 연동 절차

  1. 의존성 추가: build.gradlespring-boot-starter-amqp를 추가합니다.

  2. application.yml 설정: RabbitMQ 서버의 접속 정보를 설정합니다.

  3. 메시지 생산자 (Producer) 구현:

    • RabbitTemplate이라는 Spring이 제공하는 템플릿 클래스를 주입받습니다.
    • rabbitTemplate.convertAndSend("exchange-name", "routing-key", messageObject) 메서드를 호출하여 메시지를 발송합니다.
  4. 메시지 소비자 (Consumer) 구현:

    • @RabbitListener 어노테이션을 사용하여, 특정 큐를 리스닝하는 메서드를 간단하게 만들 수 있습니다.
    • Spring AMQP는 이 어노테이션을 감지하여, 해당 큐에 메시지가 들어올 때마다 자동으로 이 메서드를 실행해줍니다.
    // Producer (Service)
    @Service
    @RequiredArgsConstructor
    public class OrderService {
        private final RabbitTemplate rabbitTemplate;
    
        public void createOrder(OrderRequest request) {
            // ... 주문 생성 로직 ...
            // 주문 완료 이벤트를 메시지로 발송
            rabbitTemplate.convertAndSend("order.exchange", "order.created", new OrderEvent(orderId));
        }
    }
    
    // Consumer (Listener)
    @Component
    public class NotificationListener {
        
        @RabbitListener(queues = "notification.queue")
        public void handleOrderCreatedEvent(OrderEvent event) {
            // 주문 생성 이벤트를 받아 이메일 발송 등의 후처리 작업 수행
            System.out.println("주문 생성 알림: " + event.getOrderId());
        }
    }

📌 요약

  • 메시지 큐(MQ)는 애플리케이션 간의 통신을 비동기적으로 처리하고, 시스템을 느슨하게 결합하여 안정성과 확장성을 높이는 핵심적인 미들웨어입니다.
  • RabbitMQAMQP 프로토콜을 사용하는 대표적인 메시지 브로커로, Exchange, Queue, Binding이라는 구성 요소를 통해 정교한 메시지 라우팅을 지원합니다.
  • Spring AMQP를 사용하면, RabbitTemplate으로 메시지를 쉽게 생산하고, @RabbitListener 어노테이션으로 메시지를 간편하게 소비하여, Spring Boot 애플리케이션에 RabbitMQ를 손쉽게 통합할 수 있습니다.

0개의 댓글