

https://oingdaddy.tistory.com/166
확장성 및 유연성
RabbitMQ는 메시지 큐 시스템으로서, 분산 환경에서 메시지 전달을 지원하고 여러 개의 애플리케이션 간 통신을 가능하게 합니다.
다수의 웹 소켓 클라이언트 및 백엔드 서비스 간의 통신을 용이하게 만들어 확장성과 유연성을 제공합니다.
메시지 라우팅 및 패턴 매칭
RabbitMQ는 메시지 라우팅을 위한 다양한 패턴을 제공합니다. 메시지 라우팅을 통해 특정 주제 또는 대상에 대한 메시지를 효율적으로 처리할 수 있습니다.
Pub-Sub 패턴 지원
RabbitMQ는 발행-구독 (Pub-Sub) 패턴을 지원하여 여러 클라이언트가 메시지를 동시에 수신할 수 있도록 합니다. 이는 다수의 WebSocket 클라이언트에 실시간 데이터를 효과적으로 배포하는 데 도움이 됩니다.
분산 아키텍처 지원
RabbitMQ는 분산 아키텍처를 지원하므로 여러 노드 간에 메시지를 전송할 수 있습니다. 이는 대규모 및 분산된 시스템에서 중요한 기능입니다.
docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 -p 61613:61613 --restart=unless-stopped rabbitmq:management
docker exec rabbitmq rabbitmq-plugins enable rabbitmq_stomp
RabbitMQ stomp 플러그인 활성화
/exchange/<name>/<pattern> 형식의 목적지를 사용할 수 있다.<pattern>이 제공된 경우, 큐를 <name> Exchange에 <pattern>으로 바인딩하고 큐 구독을 등록한다./exchange/<name>/<routing-key>의 형식을 사용한다.<routing-key>를 사용하여 Exchange <name>으로 전송한다.유니캐스트, 멀티캐스트, 브로드캐스트 비교
- 유니캐스트(Unicast) : 1 대 1(특정 단일)
- 브로드캐스트(Broadcast) : 1 대 다수(불특정 다수)
- 멀티캐스트(Multicast) : 1 대 다수(특정 집단)
Producer의 메시지들을 어떤 Queue로 발송할지 결정, 일종의 Router개념으로 4가지 타입이 있습니다.
Fanout Exchange (Broadcast)
@Bean
public FanoutExchange chatFanoutExchange() {
return new FanoutExchange("<exchange 명>");
}
Direct Exchange (Private Messages)
@Bean
public DirectExchange chatDirectExchange() {
return new DirectExchange("<exchange 명>");
}
Topic Exchange (Group Chat)
@Bean
public TopicExchange chatTopicExchange() {
return new TopicExchange("<exchange 명>");
}
용도: Fanout Exchange나 Direct Exchange에서 메시지를 받기 위한 용도로 사용됩니다.
기본적으로 RabbitMQ에서 STOMP로 클라이언트가 Subscribe한다면 각 클라이언트마다 큐는 자동으로 동적으로 생성이 됩니다.
하지만 필요에 의해 메세지 데이터 저장, application 마다 데이터 처리 등 이 필요할때 사용하면 됩니다.
@Bean
public Queue queue() {
return new Queue("<큐 이름>", true);
}
정의한 Queuesms exchange에 바인딩되어 메시지를 수신할 수 있도록 설정되어야 합니다
@Bean
public Binding binding(Queue queue, FanoutExchange exchange) {
return BindingBuilder.bind(queue).to(exchange);
}
@Bean
public Binding binding(Queue queue, DirectExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("<routing-key>");
}
@Bean
public Binding binding(Queue queue, TopicExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("<routing-key>");
}
1. 클라이언트 식별 및 라우팅
- 클라이언트가 접속할 때, 해당 클라이언트를 식별할 수 있는 유일한 식별자를 부여합니다. 이는 클라이언트의 세션 ID, 사용자 ID, 또는 다른 식별자일 수 있습니다.
2. Exchange 및 Queue 구성
- 각 클라이언트에 대해 개별적인 exchange와 queue를 생성합니다. 이때, exchange는 direct exchange로 설정하고, 각 클라이언트의 식별자를 라우팅 키로 사용합니다.
@Bean
public DirectExchange chatDirectExchange() {
return new DirectExchange("<exchange 이름>");
}
3. 클라이언트에게 메시지 전송
rabbitTemplate.convertAndSend("<exchange 이름>", "<클라이언트의 식별자>", "<전송할 메시지>");
이러한 구조를 통해 클라이언트가 접속한 인스턴스에만 메시지가 전달되고, 다른 인스턴스는 해당 메시지를 수신하지 않게 됩니다. 각 Application 인스턴스는 자신의 exchange와 queue를 가지고 있어서, 메시지가 해당 클라이언트로 정확히 라우팅됩니다.
이와 같은 방식으로 RabbitMQ를 이용하면 클라이언트가 연결된 인스턴스에만 데이터를 전송할 수 있으며, 불필요한 데이터 전송을 방지할 수 있습니다.
4. 메시지 수신 (Consumer):
@RabbitListener 어노테이션을 사용하여 특정 Queue에서 메시지를 수신하는 메소드를 정의합니다./exchange/<exchange 명>/<routing-key>
따라서, 각 클라이언트는 자신의 exchange와 queue를 가지고 있어서 메시지가 해당 클라이언트로 정확히 라우팅됩니다. 다른 클라이언트가 접속한 인스턴스는 자신의 exchange와 queue에만 메시지를 수신하기 때문에, 클라이언트가 연결된 인스턴스에만 데이터가 전송되고, 불필요한 데이터 전송을 방지할 수 있습니다.
reference :