= 메시지 브로커
메시지 브로커 = 애플리케이션, 시스템 및 서비스가 서로 통신을 잘 할 수 있게 해주는 SW
메시지를 보낸 송신자로부터 수신자에게 잘 전달해 줌
RabbitMQ는 메시지
라는 데이터의 단위를 큐
에 저장한 후에 전달한다.
RabbitMQ가 지원해주는 특징에 대해 알아보자.
비동기적으로 데이터를 처리하기때문에 시스템의 응답성
을 높일 수 있다.
메시지는 대규모 시스템에서 엄청나게 많은 양이 발생하게된다.
RabbitMQ를 통해 메시지를 분산시키면서 부하를 나눌 수 있다.
(아래 부분 실습의 가장 마지막에 나오는 개념이다.)
메시지를 안전
하게 저장하기때문에 시스템 장애 시 발생할 수 있는 데이터 손실에 강하다.
RabbitMQ도 방법 중 하나일뿐 절대적인 방법이 아니다.
장점과 단점을 알아본다.
특징에서도 살펴볼 수 있듯 메시지 손실이 나지않도록 하는데, 이는 RabbitMQ가 메시지를 디스크
공간에 저장하기 때문이다.
또한, ACK를 지원하기때문에 확실한 데이터 전달을 할 수 있다.
메시지를 받았을때 "나 잘받았어~" 라는 의미로 ACK를 송신자에게 답장으로 날려준다.
다양한 메시지 패턴을 가지고 있고, AMQP, STOMP, MQTT 같은 대표적인 메시지관련 프로토콜을 지원한다.
클러스터링을 통해 여러 노드가 존재하는 환경에서 부하 분산을 제공한다.
여러개의 RabbitMQ 노드가 있는 환경에서 하나의 RabbitMQ를 사용하는 것처럼 묶어준다.
높은 메시지 처리량을 가지고있기때문에 적절히 구성된 환경에서 효과적으로 사용된다.
장점만 있을 수는 없다.
단점을 살펴보자.
클러스터링 환경이나 분산환경에서 장점을 가지고 있지만 설정이나 운영 측면에서 복잡하다.
메시지 처리량은 높기에 장점이지만, RabbitMQ의 경우 모든 메시지를 중앙 브로커
에게 전달함으로 오버헤드 발생의 위험이 존재한다.
RabbitMQ의 장단점을 알아봤고, 이제 구성 요소를 알아보자
RabbitMQ는 데이터를 전달하는 메시지 브로커이다. 이렇게 전달되는 데이터의 단위를 메시지
라고 부른다.
프로듀서는 데이터의 단위인 메시지
를 생성하고 RabbitMQ에 전달하는 역할을 한다.
RabbitMQ 내부에 메시지가 저장되는 장소이다.
큐(Queue)는 우리가 잘 알고있는 자료구조로 FIFO구조의 자료구조를 말한다.
먼저 들어간 메시지를 가장 먼저 처리하는 순서를 가지고 있다.
큐에 저장되어있는 메시지를 가져와 처리해주는 역할을 한다.
메시지 브로커가 메시지를 큐로 라우팅하는 방식을 말한다.
쉽게 말해 그냥 메시지를 큐로 연결
시키는 방법들이다.
라우팅 키가 정확히 일치
하는 큐로 메시지를 보낸다.
라우팅 키가 error 인 메시지는 error라는 바인딩 키를 가진 큐로 전달된다.
라우팅 키의 패턴
을 사용하여 메시지를 라우팅한다.
라우팅 키가 quick.orange.rabbit인 메시지는 바인딩 키가
*.orage.*
인 큐로 전달된다.
라우팅 키를 무시
하고 교환기에 바인딩된 모든 큐로 메시지를 브로드캐스트
한다.
모든 바인딩된 큐로 메시지가 전달된다.
라우팅 키 대신 메시지의 헤더
를 기반으로 메시지를 라우팅한다.
헤더 값과 바인딩된 헤더값이 일치하는 큐로 메시지를 전달한다.
코드로 rabbitMQ를 직접 동작해보자!
market exchange를 거쳐 각각 .product, .payment라는 이름의 queue로 메시지들이 바인딩되는 과정이다.
특징으로는 product 큐로 들어가는 메시지는 기능은 동일한 두 개의 product 어플리케이션으로 향한다. 어떻게 될까 ? 🤷♂️
Queue, Binding, Exchange 관련 메소드를 정의한다.
Binding 의 경우 to(), with() 메소드를 써서 목적지와 함께 보내준다.
서비스단에서 RabbitTemplate을 선언하고 Controller에서 해당 메소드를 호출한다.
rabbitMQ 웹에서 market이라는 exchange가 생성되고 두개의 큐도 확인할 수 있다.
queue에 현재 메시지가 적재되어있는 상황이고 다음 경로가 없기때문에 메시지가 빠지지않고있다.
이후 큐에서 다음 동작으로 가는 단계에는 Payment 서비스 단에서 endpoint로 보내고 확인해 볼 수 있다.
@RabbitListener
를 통해서 큐를 바라보게하고 해당 메소드를 호출하게한다.
PaymentApplication을 boot run 하게되면 해당 로그를 통해 메시지 5개를 처리했다는 것을 알 수 있다.
rabbitMQ에서도 market.payment라는 이름을 가진 큐에 적재되어있던 메시지 5개가 빠져나간 모습을 확인할 수 있다!
Product 서비스는 처음 예시 그림과 같이 같은 파일을 두개로 나눠서 보내려고한다.
Product의 엔드포인트도 Payment와 동일하게 설정해주고
똑같은 프로젝트를 복사해서 두개 모두 run을 했고, 두 어플리케이션 모두 큐에 메시지가 적재되기를 기다린다.
큐에 메시지를 넣게되면 어떻게 될까? 🤔
product-1
product-2
총 11개의 메시지를 큐에 넣었을때 다음과 같은 결과가 나온다.
rabbitMQ는 로드밸런싱을 수행해 라운드로빈형식으로 메시지를 전달한다는 점을 알 수 있다 !!