언어 및 프레임워크/Spring Boot

Spring Boot 시리즈 20편 – 메시지 큐 기반 비동기 아키텍처: Kafka, RabbitMQ로 확장성 강화

B컷개발자 2025. 4. 29. 12:50
728x90

Spring Boot에서 Kafka와 RabbitMQ를 활용해 메시지 큐 기반 비동기 아키텍처를 구축하는 방법을 소개합니다. 확장성, 안정성, 비동기 통신 구조를 실전 사례로 설명합니다.


Spring Boot 시리즈 20편 – 메시지 큐 기반 비동기 아키텍처: Kafka, RabbitMQ로 확장성 강화

서비스 트래픽이 증가하거나, 마이크로서비스 간 통신이 복잡해질 때,
모든 요청을 동기적으로 처리하는 구조는 한계에 부딪힙니다.

이때 필요한 것이 바로 **메시지 큐(Message Queue)**입니다.
이번 글에서는 Spring Boot로

  • Kafka (분산 스트리밍 플랫폼)
  • RabbitMQ (고전적인 메시지 브로커)
    를 이용해 확장성과 안정성을 갖춘 비동기 아키텍처를 구축하는 방법을 소개합니다.

📌 1. 메시지 큐를 도입해야 하는 이유

문제 상황 메시지 큐 도입 효과

요청 폭주로 서버 과부하 큐에 요청을 쌓아 부하 분산
복잡한 시스템 간 호출 비동기 메시지 전송으로 통합
일시적 오류 복구 필요 재시도(Retry) 메커니즘 지원
데이터 처리 시간 지연 응답과 별개로 비동기 처리 가능

✅ 2. Kafka vs RabbitMQ 간단 비교

항목 Kafka RabbitMQ

아키텍처 분산 스트리밍 전통적 메시지 브로커
메시지 모델 토픽 기반 큐 기반
처리량 매우 높음 (수십만 TPS) 중간 (수천 ~ 수만 TPS)
사용 사례 로그 수집, 이벤트 스트리밍 업무 처리, 비동기 워크플로우
신뢰성 높은 내구성 (디스크 저장) 메시지 확인(Ack) 기반

실무 기준

  • 대규모 실시간 스트림 → Kafka
  • 업무 이벤트 처리 → RabbitMQ

🛠️ 3. Spring Boot에서 Kafka 적용하기

1️⃣ Gradle 의존성 추가

implementation 'org.springframework.kafka:spring-kafka'

2️⃣ Kafka Producer 설정

@Service
@RequiredArgsConstructor
public class EventProducer {

    private final KafkaTemplate<String, String> kafkaTemplate;

    public void sendEvent(String topic, String message) {
        kafkaTemplate.send(topic, message);
    }
}

3️⃣ Kafka Consumer 설정

@Service
@Slf4j
public class EventConsumer {

    @KafkaListener(topics = "order-topic", groupId = "order-group")
    public void listen(String message) {
        log.info("Received message: {}", message);
    }
}

4️⃣ application.yml 설정 예시

spring:
  kafka:
    bootstrap-servers: localhost:9092
    consumer:
      group-id: order-group
      auto-offset-reset: earliest
    producer:
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.apache.kafka.common.serialization.StringSerializer

🐇 4. Spring Boot에서 RabbitMQ 적용하기

1️⃣ Gradle 의존성 추가

implementation 'org.springframework.boot:spring-boot-starter-amqp'

2️⃣ RabbitMQ Sender

@Service
@RequiredArgsConstructor
public class MessageSender {

    private final RabbitTemplate rabbitTemplate;

    public void send(String queueName, String message) {
        rabbitTemplate.convertAndSend(queueName, message);
    }
}

3️⃣ RabbitMQ Listener

@Service
@Slf4j
public class MessageListener {

    @RabbitListener(queues = "order-queue")
    public void receive(String message) {
        log.info("Received from RabbitMQ: {}", message);
    }
}

4️⃣ application.yml 설정 예시

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

🔥 5. 메시지 큐 설계 시 주의사항

항목 주의점

메시지 중복 처리 Consumer는 멱등성(Idempotency) 고려
오류 처리 Dead Letter Queue(DLQ) 설정 필수
모니터링 Kafka UI, RabbitMQ Management Plugin 활용
성능 튜닝 Kafka: 파티션 수 조정, RabbitMQ: Prefetch Count 조정
장애 대비 브로커 클러스터 구성, 복제(Replication) 설정

✅ 마무리 요약

항목 요약

Kafka 적용 초고속 스트림 처리, 대용량 트래픽 대응
RabbitMQ 적용 복잡한 비즈니스 워크플로우 처리
Spring Boot 연동 Starter 기반 간단 연동 가능
설계 팁 중복 메시지 처리, 장애 복구 구조 반드시 고려
확장 방향 대규모 이벤트 기반 아키텍처(EBA)로 발전 가능

📌 다음 편 예고

Spring Boot 시리즈 21편: 비동기 처리와 병렬 프로그래밍 – @Async, CompletableFuture, Reactor 실전 사용법

728x90