- 관련 연구 2 - RabbitMQ
스프링 클라우드(Spring Cloud), MQ(Message Queuing) 를 연동한 서비스 도입 사례를 공유합니다.
관련 연구 2 - RabbitMQ (현재글)
관련 연구 3 - Spring Cloud Stream, RabbitMQ 연동
도입 사례 1 - Spring Cloud Stream, RabbitMQ 실제 서비스 연동
도입 사례 2 - 예상했던, 예상하지 못했던 추가 작업
부록 A - Spring Cloud Stream 버전 이슈
정리
사내 서비스 개선사항이기 때문에 공개하기 어려운 대외비는 내용에서 제외하였습니다. 서비스 아키텍처는 외부에 공유해도 되겠다는 판단으로 공유합니다. 개선사항 의견을 말씀해 주시면 감사드리겠습니다.
이전 포스팅 참고부탁드립니다.
https://brunch.co.kr/@springboot/2
https://brunch.co.kr/@springboot/3
이번 글에서는 RabbitMQ 에 대해서 간략하게 정리를 해볼려고 합니다. 기초적인 내용이 포함되어 있으니 MQ 서비스에 대해서 잘 아시는 분은 안보셔도 되며, RabbitMQ 공식 가이드 홈페이지에 자세한 설명을 참고하시면 됩니다.
https://www.rabbitmq.com/tutorials/amqp-concepts.html
AMQP란 무엇인가? AMQP 는 Advanced Message Queuing Protocol 의 약자로 시스템 간 메시지를 교환하기 위해 공개 표준으로 정의한 프로토콜 입니다. 해당 프로토콜을 사용하는 대표적인 MQ 미들웨어가 바로 RabbitMQ 입니다. RabbitMQ 공식 홈페이지에서 확인하실 수 있으며 국내 서적으로는 [RabbitMQ 따라잡기 - 에이콘출판사] 를 참고하시면 좋을 듯 합니다.
AMQP : 시스템 간 메시지를 교환하기 위해 공개 표준으로 정의한 프로토콜
Broker : 발행자가 만든 메시지를 저장
Virtual Host : Broker 내의 가상 영역
Connection : 발행자와 소비자, Broker 사이의 물리적인 연결
Channel : 발행자와 소비자, Broker 사이의 논리적인 연결, 하나의 Connectoin 내에 다수의 Channel 설정 가능
Exchange : 발행한 모든 메시지가 처음 도달하는 지점으로 메시지가 목적지에 도달할 수 있도록 라우팅 규칙 적용
Queue : 메시지가 소비되기 전 대기하고 있는 최종 지점으로 Exchange 라우팅 규칙에 의해 단일 메시지가 복사되거나 다수의 큐에 도달
Binding : Exchange 와 Queue 간의 가상 연결
AMQP 모델에서는, 메시지 확인 개념이 있습니다. 메시지가 소비자가에게 전달되면 소비자는 Broker 에서 알림니다. 메시지 확인이 되면 Broker는 Queue 에서 메시지를 완전히 제거합니다. 그리고, 가장 중요한 개념이 바로 Exchange 입니다. 발행자로 부터 수신한 메시지를 적절한 Queue 에 분배하는 라우터의 기능을 합니다. 각, Exchange 와 Queue 는 Binding 이 되어있고(가상연결) Exchange는 수신한 메시지를 이 Binding 규칙에 따라서 적당한 Queue 에 라우팅 한다는 얘기입니다. 그리고 라우팅 기준을 정한것이 바로 Exchange Type 입니다. Kafka 와 가장 큰 차이점이기 때문에 매우 중요한 개념입니다.
크게는 3가지 타입의 Exchage가 있습니다. Direct, Topic, Fanout Exchange 입니다. Direct Type 은 라우팅 와 바인딩 키가 완벽하게 일치하는 경우에 전달하는 방식입니다.
각 Queue 는 X 라는 Exchange 와 Binding(바인딩)이 되고, 각각 orange, black, green 으로 바인딩이 되어있습니다. 발행자(P) 가 X Exchange 에 메시지를 보내면서 라우팅 키 를 black 또는 green 으로 설정했다면, 해당 메시지는 Q2 에만 전송이 됩니다. Direct Type 은 멀티 바인딩도 가능합니다. 아래와 같이 두개의 Queue 가 동일하게 black 라는 바인딩 키로 바인딩이 되어있다면, 메시지는 Q1, Q2 동시에 전송이 됩니다.
참고로 Q1 에 두개의 소비자가 그룹으로 연결되어 있다면 메시지는 번갈아가면서 전송이 되게 됩니다. 각 소비자에게 모두 전송하기 위해서는 각각의 다른이름의 Queue 를 생성해서 소비자를 연결해야 합니다.
Fanout Type 은 바인딩이 되어있는 모든 큐에 메시지를 전송합니다. 라우팅키, 바인딩키 상관없이 무조건 전달합니다. 메시지 브로드 캐스트 라우팅 방식입니다.
대규모 멀티 플레이어 온라인 게임에서 글로벌 이벤트에 사용할 수 있습니다. 스포츠 뉴스 사이트에서는 실시간으로 클라이언트에게 점수 업데이트를 배포하기 위해서 팬 아웃 교환을 사용할 수도 있습니다.
이제 제가 가장 이해하기 어려웠던 Topic Type 를 설명해보겠습니다. Topic 는 Exchange 와 Queue 를 바인딩할때 와일드 카드를 이용해서 바인딩을 하고, 라우팅키를 매칭을 시켜서 라우팅을 합니다. "*" 는 하나의 단어, "#"은 0개 이상의 단어를 의미합니다. 설명이 어려우니 예시를 통해서 설명을 해보겠습니다. 아래와 같이 X 라는 Topic Type Exchane 가 있고, 각 Queue1 은 *.orange.* 로 바인딩이 되어있고, Queue2 는 *.*.rabbit 와 lazy.# 으로 바인딩이 되어있습니다.
자... P라는 발행자가 X 라는 Exchane 에 food.orange 이라는 라우팅키로 메시지를 전송을 하면 어떤 큐로 메시지가 전송이 될까요? 어떤 큐에도 메시지는 전송이 되지 않습니다. 그럼 다시, food.orange.sign 이라는 라우팅 키로 메시지를 전송을 하면 어떤 큐로 메시지가 전송이 될까요? Q1 로 메시지가 전송이 됩니다. food.orange.sign 이 *.orange.* 과 매칭이 되기 때문에 *.orange.* 로 바인딩이 되어있는 Q1 에 메시지가 전송이 되는 것입니다. 그럼 lazy.test.rabbit 라는 라우팅 키로 메시지를 보내면 Q2 로 메시지가 전송이 될까요? 네 전송이 됩니다. lazy.# 에서 # 은 0개 이상의 단어와 매칭이 되기 때문입니다. 불친절한 설명 죄송하며 레퍼런스 자료를 참고하시면 큰 도움이 되실 것 같습니다.
https://www.rabbitmq.com/tutorials/tutorial-five-java.html
RabbitMQ 공식 가이드를 보면 Topic 타입에 대해서 아래와 같이 추가 설명이 되어있습니다.
Topic exchange is powerful and can behave like other exchanges. When a queue is bound with "#" (hash) binding key - it will receive all the messages, regardless of the routing key - like in fanout exchange. When special characters "*" (star) and "#" (hash) aren't used in bindings, the topic exchange will behave just like a direct one.
영어를 잘 못해서 너무 어렵지만, 어렵게 어렵게 번역을 해보면... Topic Type 의 Exchange 는 다른 타입의 Exchnage, 즉 Direct 또는 Fanout Type 처럼 사용할 수 있다고 합니다. Exchange 와 Queue 의 바인딩을 # 으로만 되어있다면 Exchange 에 메시지를 보낼 때 라우팅키와 상관없이 모든 Queue 에 메시지가 전송이 됩니다. 왜냐면, # 은 0개 이상의 단어와 매칭이 되기 때문입니다. 즉!!! Fanout Exchange 와 같이 사용이 됩니다. 또한, Topic Type 의 Exchange 에 바인딩이 되어있는 Queue 와 Exchange 의 바인딩키에 # 또는 * 이 전혀 사용되지 않았다면??? 이 경우에는 발행자가 Exchange 에 보내는 라우팅 키와 바인딩키가 정확히 일치해야만 메시지가 Queue 로 전송이 됩니다. 즉, Direct Type 처럼 사용이 된다는 얘기입니다. 주저리주저리 했지만 결론은!!
RabbitMQ의 Topic 타입은 은 Direct Type 처럼, Fanout Type 처럼 사용이 가능합니다.(바인딩키를 어떻게 설정하는지에 따라서)
죄송합니다만 생략합니다. 블로그 또는 공식 가이드 홈페이지에서 참고하시면 많은 도움이 되실것 같습니다.
이번 [관련 연구 2 - RabbitMQ]에서는 RabbitMQ 에 대해서 아주 간략하게 글을 작성해봤습니다. 다음 글에서는 [관련 연구 3 - Spring Cloud, Spring Cloud Stream] 라는 주제로 글을 쓸 예정입니다.
https://brunch.co.kr/@springboot/9