본문 바로가기

RabbitMQ

RabbitMQ란?

RabbitMQ란?
서버간 메세지를 전달해주는 오픈소스 메세지 브로커이다. 
A → B에게 또는 A → B,C,D,E,F ... 등 메세지를 보내려고 할 때 RabbitMQ가 이 메세지를 받아서 전달 해주는 것으로 이해하면 된다.

RabbitMQ는 AMQP프로토콜을 구현한 메세지 브로커인데, 여기서 AMQP란 Advanced Message Queuing Protocol로 client application과 middleware broker와의 메세지를 주고 받기 위한 프로토콜이다.

https://www.rabbitmq.com/

 

Messaging that just works — RabbitMQ

Developer Experience Deploy with BOSH, Chef, Docker and Puppet. Develop cross-language messaging with favorite programming languages such as: Java, .NET, PHP, Python, JavaScript, Ruby, Go, and many others.

www.rabbitmq.com

 

 

RabbitMQ에서 메세지를 전송하고 받을 때 구성이다.

rabbitMQ 설명 이미지

 

MSA구조의 서버를 사용하다 보면, 서버와 서버끼리 메세지를 주고받아야할 때가 있는데, 이때 RabbitMQ를 사용한다.

서버1이 서버2에게 메세지를 보낼 때 때 rabbitMQ를 통해 메세지를 전송한다.
이때 서버1이 producer가 되는 것이고, 서버2가 consumer가 되는 것이다.

반대로, 서버2가 서버1에게 메세지를 보낼 때 
서버2가 producer가 되고 서버1이 consumer가 되는 것이다.


 

* Exchange
producer에게 받은 message를 queue에게 전달해준다.
queue에게 전달할 때는 4가지 타입이 있다.

1. Fanout
2. Direct
3. Topic
4. Headers

이 4가지 타입들은 producer에게 전달 받은 메세지를 어떤 queue에게 발송 할 지 라우팅을 결정하는 것이다.
아래에 좀 더 자세히 설명을 작성했다!


* Binding
exchange와 queue와의 관계를 의미한다.
binding이 되어있어야 exchange가 queue에게 메세지를 전달 할 수 있다.
exchange 규칙으로 어떻게 라우팅이 될지 결정 되었으면,
binding은 결정된 메세지를 어떤 queue에게 전달할 지 라우팅할 규칙을 결정하는 것이다.

즉, exchange는 라우팅을 결정하고 binding은 라우팅할 수 있는 규칙을 지정하는 것이다. 그래서 특정조건에 맞는 메세지를 특정 큐에 전송하도록 해준다.


* Queue
exchange는 producer로부터 전달 받은 메세지를 binding되는 queue들에게 동일하게 전달한다.

이때, queue는 전달받은 메세지들을 consumer들에게 전달한다. 이때 공평하게 전달하기 위해 round-robin스케줄로 메세지를 전달한다.
queue는 consumer들에게 전달되기 전에 메모리나 디스크에 저장해놓는다.


 

Exchange 4가지 타입

1. Fanout

exchange와 binding된 모든 queue에게 동일한 메세지를 보낸다. 전체메세지 같은 것이다.

 



2. Direct

direct_example_1

 

direct example_2

 

routing key를 활용하여 라우팅 한다. 이 말은 exchange에서 보낸 메세지를 routing key를 통해 queue와 직접 binding 할 수 있다.

RabbitMQ에서 사용되는 디폴트 exchange는 Direct이다. RabbitMq에서 생성되는 queue가 자동으로 binding되고, 이때는 각 queue의 이름이 routing key로 지정된다.

하나의 queue에 여러개의 routing key를 지정할 수 있고 ( 예시 :direct example_2에서 routing key가 error 인 것 ),
여러 queue에 동일한 routing key를 지정할 수 있다. ( 예시 :direct example_2에서 두번째 queue가 routing key가 총 3개로 지정되어있다.)

즉, 메세지의 routing key를 기반으로 queue와 1:N을 할 수 있다.



3. Topic

routing key패턴이 일치하는 queue에 메세지를 전달한다. direct는 routing key가 완전 일치해야 메세지를 전달 할 수 있는데, topic은 패턴을 정해서 binding 규칙을 정의하기 때문에 direct방식보다는 좀 더 유연하게 정의해서 메세지를 전송할 수 있다. ( topic은 패턴만 일치하면 binding이 된다.)

이때, 규칙은
* : 단어 1개를 대체
# : 0개 이상의 단어를 대체 (없거나 하나 이상의 단어를 의미)

어떤 queue에 routing key를 2개 지정했을 때,
만약 routing key가 topic패턴에 모두 일치하게 되었다고 가정해본다.
그러면 메세지 전달이 2번 되는 것이 아니라 queue에 1번만 전달된다.
즉, 하나의 queue에 N개의 routing key가 있고, 패턴도 모두 일치한다고 하더라도 메세지 한번만 전달된다.

(예시 _ producer에서 routing key를 지정하여 메세지를 보낼 때)
1. routing key를  quick.orange.rabbit으로 지정하여 전송했을 때 : Q1과 Q2 모두 메세지를 받는다.

2. routing key를  quick.orange.fox로 지정하여 전송했을 때 : Q1만 메세지를 받는다.

3. routing key를  lazy.brown.fox로 지정하여 전송했을 때 : Q2만 메세지를 받는다.

4. routing key를  quick.brown.fox로 지정하여 전송했을 때 : 메세지를 받는 Queue는 없다.

5. routing key를 quick.orange.male.rabbit으로 지정하여 전송했을 때 : 메세지를 받는 Queue는 없다.
   -> *.orange.*이기 때문에 1개의 단어만 대체 할 수 있어서 Q1은 받을 수 없다.

6. routing key를 lazy.orange.male.rabbit으로 지정하여 전송했을 때 : Q2만   
   -> lazy.#이기 때문에 #은 0개 이상의 단어를 대체할 수 있어서 가능한 것이다.

7. routing key를 orange로 지정하여 전송했을 때 : 메세지를 받는 Queue는 없다.



4. headers

key-value로 정의된 헤더에 의해 메세지를 queue에 전달하는 방법이다.
메세지를 전달하는 producer쪽에서 정의하는 header의 key-value와 메세지를 받는 consumer쪽에서 정의된 argument의 key-value가 일치하면 binding된다.

producer에서 정의하는 header는 메세지와 함께 전송되고, consumer쪽에서는 exchange와 queue가 binding되는 시점에 argument를 정의한다.

header에는 x-match라는 key가 있다. 그리고 옵션값으로는 any와 all이 있다.

1) x-match : all
header의 key-value와 argument의 key-value가 정확히 일치해야 binding된다.

2) x-match : any
producer가 전송하는 header의 key-value 값과 argument의 key-value값 중 하나라도 일치하는것이 있으면 binding된다.














참고 및 이미지 출처
https://www.rabbitmq.com/getstarted.html

https://hwannny.tistory.com/82
https://blog.dudaji.com/general/2020/05/25/rabbitmq.html

'RabbitMQ' 카테고리의 다른 글

RabbitMQ admin 계정 새로 만들기  (0) 2022.04.29