본문 바로가기

Kafka, RabbitMQ

RabbitMQ에 대해 알아보자 - (9) Topic 패턴 / Topic Exchange 전략

들어가기 앞서

RabbitMQ에서 Topic 패턴은 보다 유연한 메시지 라우팅이 필요할 때 사용하는 전략입니다.

 

Direct Exchange가 단일 라우팅 키로 메시지를 분기하는 방식이라면, Topic Exchange는 패턴 매칭을 통해 동적으로 메시지를 다양한 큐에 분배할 수 있는 것이 특징입니다. 복잡한 메시지 분기 구조가 필요한 서비스(예: 마이크로서비스 간 이벤트 전파, 로그 분류, 사용자 그룹별 알림 시스템 등)에 적합하게 사용됩니다.

Topic 패턴 / Topic Exchange 전략

 

  • 동작 : 라우팅 키 패턴을 이용해 다수 큐로 메시지 분기
  • Exchange : Topic Exchange
  • 사용 예제 : 로그 수집 (info.log, error.db 등), 마이크로서비스 이벤트 분배, 역할/지역 기반 라우팅 등

Topic 모델 / Topic Exchange 전략

Topic Exchange는 메시지를 보낼 때 .(dot)으로 구분된 라우팅 키를 사용하고, 큐에서는 이를 패턴으로 바인딩하여 메시지를 수신합니다.

 

패턴은 두 가지 와일드카드를 지원합니다:

  • * (별표) : 단일 단어와 매칭
  • # (샵) : 0개 이상의 단어와 매칭

예를 들어 "log.error.db"라는 라우팅 키는 다음과 같은 패턴에 매칭됩니다:

  • log.*.*
  • log.#
  • #.db

코드 예시

1. 메시지 발행

@Component
@RequiredArgsConstructor
public class TopicProducer {

    private final RabbitTemplate rabbitTemplate;

    public void send(String routingKey, String message) {
        rabbitTemplate.convertAndSend(RabbitMqConfig.TOPIC_EXCHANGE, routingKey, message);
    }
}

 

프로듀서에서 라우팅 키와 메시지를 지정하면, Topic Exchange는 해당 키를 패턴에 맞춰 큐로 전달하게 됩니다.


2. 설정 파일 (RabbitMqConfig)

@Configuration
public class RabbitMqConfig {

    public static final String TOPIC_EXCHANGE = "topicExchange";
    public static final String QUEUE_ONE = "topic.queue1";
    public static final String QUEUE_TWO = "topic.queue2";

    @Bean
    public Queue queue1() {
        return new Queue(QUEUE_ONE, true);
    }

    @Bean
    public Queue queue2() {
        return new Queue(QUEUE_TWO, true);
    }

    @Bean
    public TopicExchange topicExchange() {
        return new TopicExchange(TOPIC_EXCHANGE);
    }

    @Bean
    public Binding bindingQueue1(Queue queue1, TopicExchange topicExchange) {
        return BindingBuilder.bind(queue1).to(topicExchange).with("log.*");
    }

    @Bean
    public Binding bindingQueue2(Queue queue2, TopicExchange topicExchange) {
        return BindingBuilder.bind(queue2).to(topicExchange).with("log.#");
    }
}
 
  • queue1은 log.* 와 일치하는 키만 수신합니다. 예: log.info, log.error
  • queue2는 log.#와 일치하는 모든 키를 수신합니다. 예: log.error.db, log, log.system.down 등

3. Consumer 구성

@Component
public class TopicConsumer {

    @RabbitListener(queues = RabbitMqConfig.QUEUE_ONE)
    public void receiveQueue1(String message) {
        System.out.println("[Queue1] " + message);
    }

    @RabbitListener(queues = RabbitMqConfig.QUEUE_TWO)
    public void receiveQueue2(String message) {
        System.out.println("[Queue2] " + message);
    }
}

 

 


실행 결과

  • routingKey = "log.info"
    • queue1 (log.*) : 수신 O
    • queue2 (log.#) : 수신 O
  • routingKey = "log.error.db"
    • queue1 (log.*) : 수신 X
    • queue2 (log.#) : 수신 O

이처럼 Topic Exchange는 특정 조건이나 패턴에 맞춰 메시지를 라우팅해야 할 때 매우 유용하게 활용됩니다.