본문 바로가기

Kafka, RabbitMQ

RabbitMQ에 대해 알아보자 - (8) Routing 패턴 / Direct Exchange 전략

들어가기 앞서

RabbitMQ의 Routing 패턴은 하나의 메시지를 특정 큐에만 전달하고 싶을 때 사용하는 메시징 방식입니다.


Fanout Exchange와 달리, 라우팅 키를 기반으로 Exchange와 큐 간의 연결을 제어할 수 있다는 점이 특징입니다. 일반적으로는 Direct Exchange를 활용하며, 알림 시스템에서 사용자 역할별로 메시지를 분기하거나, 로그 레벨에 따라 로그 메시지를 구분하는 용도로 자주 사용됩니다.

Routing 패턴 / Direct Exchange 전략

  • 동작 : 라우팅 키에 따라 지정된 큐로만 메시지를 전달
  • Exchange : Direct Exchange
  • 사용 예제 : 사용자 역할 기반 알림, 로그 레벨 필터링, 주문 상태별 이벤트 처리

Routing 모델 / Direct Exchange 전략

Routing 패턴은 메시지를 발행할 때 라우팅 키를 지정하고, 해당 키에 따라 바인딩된 큐로만 메시지를 전달하는 방식입니다. Fanout과 달리 모든 큐로 메시지가 전달되지 않고, 라우팅 키가 일치하는 큐에만 메시지가 전달 됩니다. 즉, 라우팅 키를 기준으로 필터링하여 큐를 선택하는 방식이라고 보면 됩니다.

 

코드는 아래 링크에서 확인해 주시면 감사하겠습니다.

 

 

코드 예시

간단하게 코드를 살펴 보겠습니다.

@Component
@RequiredArgsConstructor
public class RoutingProducer {

    private final RabbitTemplate rabbitTemplate;

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

 

convertAndSend()의 두 번째 파라미터가 라우팅 키이며, 해당 키에 따라 바인딩된 큐에만 메시지가 전달된다.


 
@Configuration
public class RabbitMqConfig {

    public static final String INFO_QUEUE = "infoQueue";
    public static final String ERROR_QUEUE = "errorQueue";
    public static final String WARN_QUEUE = "warnQueue";

    public static final String DIRECT_EXCHANGE = "directExchange";

    @Bean
    public Queue infoQueue() {
        return new Queue(INFO_QUEUE, true);
    }

    @Bean
    public Queue errorQueue() {
        return new Queue(ERROR_QUEUE, true);
    }

    @Bean
    public Queue warnQueue() {
        return new Queue(WARN_QUEUE, true);
    }

    @Bean
    public DirectExchange directExchange() {
        return new DirectExchange(DIRECT_EXCHANGE);
    }

    @Bean
    public Binding bindInfo(Queue infoQueue, DirectExchange directExchange) {
        return BindingBuilder.bind(infoQueue).to(directExchange).with("info");
    }

    @Bean
    public Binding bindError(Queue errorQueue, DirectExchange directExchange) {
        return BindingBuilder.bind(errorQueue).to(directExchange).with("error");
    }

    @Bean
    public Binding bindWarn(Queue warnQueue, DirectExchange directExchange) {
        return BindingBuilder.bind(warnQueue).to(directExchange).with("warn");
    }
}


예를 들어 라우팅 키를 "warn"으로 메시지를 보내면 warnQueue에만 메시지가 전달된다.


@Component
public class RoutingConsumer {

    @RabbitListener(queues = RabbitMqConfig.INFO_QUEUE)
    public void infoListener(String message) {
        System.out.println("[INFO] " + message);
    }

    @RabbitListener(queues = RabbitMqConfig.ERROR_QUEUE)
    public void errorListener(String message) {
        System.out.println("[ERROR] " + message);
    }

    @RabbitListener(queues = RabbitMqConfig.WARN_QUEUE)
    public void warnListener(String message) {
        System.out.println("[WARN] " + message);
    }
}
 

컨슈머는 각각의 큐를 수신하도록 구성되어 있으며, 메시지의 라우팅 키에 따라 서로 다른 로직을 처리할 수 있다.


Direct Exchange 실행 결과

  • "info" 라우팅 키 → infoQueue만 수신
  • "warn" 라우팅 키 → warnQueue만 수신
  • "error" 라우팅 키 → errorQueue만 수신

이처럼 Routing 패턴은 메시지를 선택적으로 라우팅하는 데 유용하며, 메시지의 타입, 수준, 대상에 따라 세분화된 처리가 필요할 때 적합하다.