[RabbtiMQ] Exchange (Message broker)

2021. 11. 1. 18:50 Spring Cloud/RabbitMQ

이번 글에서는 RabbitMQ의 메세지 broker인 Exchange에 대해 알아보겠습니다.

0. Exchange란?

메세지의 Routing Key에 따라 메세지를 적절한 Queue에 분배하는 broker 역할을 수행하는 Distributer 입니다.

Exchange의 종류에는 Fanout / Direct / Topic 등이 있습니다.

1. Fanout Exchange

Fanout Exchange는 binding된 모든 Queue에 하나의 메시지를 복제해 내보냅니다.

만약 아래의 그림처럼, HR 시스템이 "x.hr" Exchange로 신규 입사자 정보를 Publish 하면 Fanout Exchange는 해당 메세지를 복제해 "q.hr.accounting"과 "q.hr.marketing"으로 전달합니다. 이후 "q.hr.accounting"의 Consumer와 "q.hr.marketing"의 Consumer는 각각 개별적으로 해당 메세지를 소비하게 됩니다.

 

 

Fanout Exchange는 binding 되어있는 모든 Queue에 메세지를 복제해 전달하므로, Routing Key가 필요하지 않습니다.

2. Direct Exchange

Direct Exchange는 binding된 Queue 중 Routing Key와 매칭되는 하나의 Queue에만 메시지를 전달합니다. binding 되어있는 Queue 중 Routing Key와 매칭되는 Queue가 존재하지 않을 경우 해당 메시지는 discard 버려지게 됩니다.

만약 아래의 그림처럼, Picture 메시지가 "x.picture" Exchange로 사진 정보를 Publish 하면 Direct Exchnage는 해당 사진의 Type을 조사해 "png/jpg"일 경우에는 해당 메세지를 "q.picture.image"로 전달합니다. 만약, 해당 사진의 타입이 "svg"일 경우에는 "q.picture.vector"로 전달합니다. 이후 "q.picture.image"의 Consumer와 "q.picture.vector"의 Consumer는 각각 개별적으로 해당 메세지를 소비하게 됩니다.

 

 

Exchange와 Queue의 binding structure는 아래와 같습니다.

 

 

3. Topic Exchange

Topic Exchange는 binding된 Queue 중 Multiple Criteria Routing Key에 일치하는 모든 Queue에 메세지를 복제해 전달합니다.

✔ * : substitute exactly one word
✔ # : substitute zero or more words

 

 

만약 Picture의 Entity가 아래와 같이 구성되어있다면

public class Picture {
    private String  name;
    private String  type;
    private String  source;
    private long    size;
}

위의 Picture의 field 값과 StringBuilder를 사용해 아래와 같이 Routing Key를 구성할 수 있습니다. (Routing Key : Source.Size.Type)

public void sendMessage(Picture p){

    StringBuilder sb = new StringBuilder();
    sb.append(p.getSource());
    sb.append(".");

    if(p.getSize() > 4000){
        sb.append("large");
    }else{
        sb.append("small");
    }

    sb.append(".");
    sb.append(p.getType());

    // routing key : source.size.type
    String routingKey = sb.toString();

    try {
        String json = objectMapper.writeValueAsString(p);
        rabbitTemplate.convertAndSend("x.picture2",routingKey, json);
    } catch (JsonProcessingException e) {
        e.printStackTrace();
    }
}

Exchange와 Queue의 binding structure는 아래와 같습니다.


참고 자료 : https://www.udemy.com/course/rabbitmq-java-spring-boot-for-system-integration/

출처 : https://minholee93.tistory.com/entry/RabbtiMQ-Exchange-Message-broker