💡 메시지 큐(MQ)에 대해 학습하고 정리한 글입니다.
Queue는 이전부터 익히 들었던 데이터 구조입니다. 큐는 2개의 끝을 가지고 있으며 각각은 머리와 꼬리의 역할을 합니다. 새로운 아이템은 꼬리로 입력되며 제거할 아이템은 머리에서 저게됩니다. 이런 구조를 FIFO(First In First Out)라고 모두 알고 계실 것입니다.
메시지 큐도 마찬가지로 Queue입니다. 큐가 메시지들로 채워져있으며 큐의 기본적인 원리를 그대로 따릅니다. 대신 머리와 꼬리와 연결된 Producer와 Consumer가 등장합니다. Proucer는 메시지 큐에 새로운 메시지를 추가하고 Consumer는 메시지 큐에서 메시지를 제거함으로 두 종단간에 데이터를 교환합니다. 비즈니스 적인 관점에서 보면 이 데이터 교환은 커머스에서 주문 유저의 회원가입 사용자의 서비스 요청이 될 수 있습니다.
Producer는 Consumer에게 정보를 전달하기 위해서 메시지큐에 새로운 메시지를 넣으면 Consumer 주기적으로 Polling하면서 새로운 메시지를 받게 됩니다. 아래의 그림이 메시지 큐의 시스템을 표현 해줍니다.

하지만 대체로 정보의 전달을 위해서는 API 통신, Socket 통신 같은 방식을 사용했지 메시지 큐를 퉁한 데이터 교환은 익숙하지 않습니다. 사용하기에 앞서 메시지 큐가 어떤 장점들이 있는지 알고 있으면 좋을 것 같습니다.
메시지 큐는 linux에서도 사용되는 IPC(Inter-Process Communication)방법입니다. 시스템 프로그래밍에서 흔하게 사용되는 데이터 송수신 도구로 거대한 양의 데이터를 다룰 때 분산해서 처리해야할 때 사용됩니다.
모니터링, 로그, 정산 등의 큰 작업에서 Queue는 여러 컴포넌트들이 데이터를 생성하고 저장할 때 버퍼 역할을 수행하게 됩니다. Producer와 Consumer의 속도가 차이가 있을때 장애가 나더라도 Queue가 버퍼 역할을 수행해주기 때문에 장애가 전파되는 일을 방지할 수 있습니다.
메시지 큐의 특징으로는 비동기성(Asynchronous), 분리(Decoupling), 탄력성(Resilience), 과잉(Redundancy), 확장성(Scalable), 보증(Guarantees)이 있습니다.
위에서 설명한 방법은 메시지 큐의 기본적인 형태이며, Producer와 Consumer의 정보 교환에는 다양한 방법론들과 프로토콜들이 존재합니다. 이 글에서 제가 비교해보고 싶은 두개의 프로토콜은 MQTT와 AMQP입니다.
MQTT는 Message Queue Telemetry Transport의 약자로 Publish-Subscribe 구조의 메시지 송수신 프로토콜입니다. HTTP 프로토콜에 비해 제한된 통신 환경과 낮은 전력으로 사용할수 있기에 주로 IoT 부야와 메신져 분야에서 사용합니다.
MQTT는 Broker Publisher Subscriber 구조를 가지고 있습니다. Publisher가 Topic을 생성하면 Subsucriber는 생성된 Topic을 구독합니다. 이들 사이에는 Broker가 존재해서 두 역할들을 중계해줍니다.
하나의 Topic에는 여러개의 Subscriber가 붙을 수 있기 때문에 1:N 관계의 통신 구축에 사용됩니다.

또한, MQTT 클라이언트에서는 세가지의 서비스 품질(QOS)를 제공합니다.
AMQP는 Advanced Message Queue Protocol의 약자로 메시지 지향 미들웨어(MOM)를 위한 개방형 표준 응용 계층 프로토콜입니다.
AMQP는 메세지 큐 구조에 Exchange라는 라우터 역할이 존재합니다. Exchange는 Publisher에게 메시지를 수신 받으면 그것을 Queue에게 분배해주는 역할을 합니다. 한개의 Queue만 있다면 일반적인 메세지 큐와 다를 것 없지만 여러 개의 Consumer와 Queue가 존재할 때 높은 효율을 보여줍니다.

AMQP에서는 Binding이라는 개념이 존재합니다. Binding은 Exchange와 Queue의 관계를 정의해 메시지를 라우팅하게 됩니다.
Direct Exchange
Direct Exchange는 Exchange로 수신된 메시지의 routing key와 Queue의 Binding key가 정확히 매칭되는 Queue로 전달됩니다.
Fanout Exchange
Fanout Exchange는 Exchange와 매칭된 모든 Queue에 메시지를 전달합니다. 1:N 관계로 메시지를 브로드캐스트합니다.
Topic Exchange
Direct Exchange와 유사한 방식이지만 고정된 routing key를 사용하는 것 대신 Wildcard를 사용합니다. 메시지는 하나 또는 여러개의 routing pattern이 맞는 Queue에 보내집니다.
Headers Exchange
마지막으로 Headers Exchange는 routing key 대신에 헤더 속성을 통해 라우팅됩니다.