WEB BE Repository/RabbitMQ

[RabbitMQ] Spring RabbitMQ 사용방법

조금씩 차근차근 2025. 9. 10. 22:24

RabbitMQ는 메시지를 수신하고 전달하는 메시지 브로커이다.

이 글은 다음 RabbitMQ 튜토리얼을 Java 버전으로 따라가 본 상태라고 가정합니다.
따라서, 주요 API의 스프링에서의 사용법을 언급하며,
스프링부트의 org.springframework.boot:spring-boot-starter-amqp
를 사용하고 있다고 가정합니다.

만약 RabbitMQ가 처음이시라면, 다음 글을 순서대로 따라가보며 내부 원리를 이해해보시길 권장드립니다.

[RabbitMQ Java] 가장 간단한 프로듀서-컨슈머 사용해보기

 

[RabbitMQ Java] 가장 간단한 프로듀서-컨슈머 사용해보기

원래 RabbitMQ 는 할 생각이 없었고, Kafka를 해보려고 했는데Kafka Definitive Guide의 내용이 너무 방대해서 당장 애플리케이션을 만들기 위한 기술에는 부적합하다고 판단했다.따라서, RabbitMQ를 공부해

dev.go-gradually.me

목차

  • 큐 등록
  • 생산자/소비자 모델
  • Pub-Sub 모델
  • Exchange
  • 바인딩 설정
    • 라우팅 설정
    • 토픽 설정
  • 메시지 송/수신
  • 스프링에서의 특징
    • 공정한 분배 vs 라운드 로빈
    • 메시지 Ack

 

스프링 메시지 송-수신

가장 간단한 메시지 송/수신 모델

큐 설정

  • amqp.core.Queue: 큐 이름 등록

  • amqp.core.AnonymousQueue: 임시 큐 등록


이때의 큐 이름은 UUID를 이용한 랜덤한 이름으로 결정된다.

Pub-Sub 모델

exchange 설정

  • FanoutExchange

  • DirectExchange

  • TopicExchange

  • HeadersExchange

바인딩 설정

  • binding 은 객체로 관리된다.
  • BindingBuilder

라우팅/토픽 설정

라우팅과 토픽 설정은 바인딩을 통해 이루어진다.

토픽 설정

  • *(별표): 정확히 한 단어를 대체한다.

  • #(해시): 0개 이상의 단어를 대체한다.


메시지 송신

  • RabbitTemplate
  • Queue: RabbitTemplate는 큐 이름을 파라미터로 받는다.

  • convertAndSend: 직렬화 후 송신. 단순 전송용 메소드
  • convertSendAndReceive: RPC용 송신 후 수신을 수행하는 메소드

스프링에선 명시적으로 reply 큐를 지정할 필요가 없다.

메시지 수신

  • @RabbitListener(queues = "queueName")
    • 이는 클래스 레벨과 메소드 레벨 모두에 붙일 수 있다.

  • @RabbitHandler: 실제 들어온 메시지를 핸들링하는 메소드

공정한 분배 vs 라운드 로빈

RabbitMQ는 기본적으로 라운드 로빈 방식으로 메시지를 소비자에게 전달한다.
이 경우 모든 소비자가 평균적으로 동일한 수의 메시지를 받게 된다.

그러나 작업의 복잡도가 다른 경우(예: 홀수 메시지는 무겁고 짝수 메시지는 가벼운 경우) 한쪽 워커는 과부하되고 다른 워커는 한가할 수 있다.

Spring AMQP는 기본적으로 공정한 분배(fair dispatch) 를 사용하고 있다.

  • AbstractMessageListenerContainer에서 DEFAULT_PREFETCH_COUNT=250
  • 즉, 워커가 250개의 메시지를 동시에 처리 중이면 새 메시지를 더 받지 않는다.
  • prefetch=1로 설정하면 라운드 로빈 방식으로 동작한다.
  • AbstractMessageListenerContainer.setPrefetchCount(int prefetchCount)

메시지 확인 (Acknowledgement)

메시지 처리에는 몇 초가 걸릴 수 있다. 소비자가 긴 작업을 처리하다가 중간에 종료된다면 어떻게 될까?

Spring AMQP는 기본적으로 보수적인 메시지 확인 방식을 사용한다.
리스너에서 예외가 발생하면 컨테이너는 다음을 호출한다.

channel.basicReject(deliveryTag, requeue)
  • 기본적으로 requeue=true 이다.
  • 명시적으로 defaultRequeueRejected=false 설정을 하거나, AmqpRejectAndDontRequeueException을 던지면 재큐잉 되지 않는다.

 

본 글은 RabbitMQ 공식 페이지의 RabbitMQ Tutorial 을 참고하여 작성되었습니다.

 

RabbitMQ tutorial - "Hello World!" | RabbitMQ

<!--

www.rabbitmq.com