Protocol

AMQP & RabbitMQ

Seung-o 2023. 9. 18. 12:21

1. 개요

RabbitMQ is the most widely deployed open source message broker.

RabbitMQ 공식 홈페이지

 

RabbitMQ를 구글에 검색하면 가장 상단에 나오는 내용이다. 일반적으로 블로그에서는 RabbitMQ를 간단하게 “AMQP를 구현한 오픈소스 메세지 브로커“ 정도로 정의한다.

위 정의를 보고 RabbitMQ가 무엇인지 단박에 알 수 있는 사람은 이 글을 보고 있지 않을 것이다. AMQP는 무엇이고, 메세지는 무엇이며 브로커는 무엇인지 궁금증이 들기 마련이다. 큐에 대한 기본적인 개념 나아가 AMQP부터 정리하며, 최종적으로 RabbitMQ가 어떤 녀석인지 알아보자.

 

2. AMQP ( Advanced Message Queue Protocol ) 란?

 

2-1. AMQP 개요

“AMQP는 메시지 지향 미들웨어(MOM)를 위한 개방형 표준 응용 계층 프로토콜입니다.”

 

과거 플랫폼 종속적인 제품들 사이에서 이기종(HSA)간에 메세지(~요청)를 교환하기 위해서는, 메세지 포맷 통일을 위해 메시지 브릿지를 사용하거나 시스템 자체를 통일해야하는 불편함과 비효율성이 존재했다. 메시지 브릿지의 성능이 좋지 않을 뿐더러, 메시지 혹은 시스템을 통일한다는 것은 리소스의 낭비로 이어졌다.

서로 다른 언어와 프로토콜로 구성된 서버들이 MSA 방식으로 작동하는 것을 생각하면 쉽게 이해할 수 있다. HTTP 방식의 노드 서버와 GRPC 방식의 고랭 서버가 통신하려고 하면, 서로가 주고 받는 요청과 응답 형태를 적절하게 변환해야하는 셈이다. 이렇게 다른 형태의 서버가 여러 개로 늘어날수록 서버 개발자 입장에서는 관리 포인트가 늘어나고, 요청 하나가 여러 개의 서버를 거칠 때마다 응답이 느려질 수 있다.

AMQP는 여기서 “메세지 지향 미들 웨어”를 위한 프로토콜로써 이 문제를 해결한다. 서로 다른 시스템간의 효율적인 통신을 위해 정해진 메시지 형태로 통신하고, 직접적인 통신이 아닌 메세지 큐를 두고 이를 거쳐서 통신하는 방식이다. 모든 서버는 미들웨어가 정한 방식대로 요청하고 응답하는 것이다.

 

MQ 모식도

 

💡 메세지 큐(MQ)란?
큐(Queue) 는 가장 대표적인 데이터 구조 중 하나이다. 고대 프랑스어 cue 꼬리에 유래되었으며, 줄을 서는 것을 뜻하는 영어로 자리잡았다. 데이터 구조 관점에서, 큐는 머리와 꼬리를 지니며, 선출선입 (FIFO)로 동작한다. 메세지 큐(Message Queue)는 큐가 메시지로 채워진 형태로, 큐의 기본적인 원리를 그대로 따른다. 메시지가 큐의 꼬리로 입력되고, 큐의 머리로 출력되며 출력된 메시지는 큐에서 제거된다. 조금 더 보태면, 꼬리에는 Producer ( 또는 Publisher )라는 것이 / 머리에는 Consumer 라는 것이 연결되어 메시지큐는 Producer과 Consumer 두 종단 간에 데이터 교환을 가능케한다.

 

AMQP는 정해진 통신 방식을 지키기 위해 아래와 같은 특징을 가진다.

  1. 모든 브로커들은 같은 방식으로 동작해야 한다.
  2. 모든 클라이언트들은 같은 방식으로 동작해야 한다.
  3. 네트워크 상으로 전송되는 명령어들이 표준화 되어있다.
  4. 프로그래밍 언어에 중립적이다.

2-2. AMQP의 라우팅 모델

AMQP의 라우팅 모델은 다음과 같다.

 

AMQP 라우팅 모델

 

  1. Producer ( Publisher ): Broker로 메세지를 전달한다.
  2. Exchange: Broker에서 Queue로 메세지를 전달한다.
  3. Queue: 메모리나 디스크에 메세지를 저장하고, 그것을 consumer에게 전달한다.
  4. Binding: Exchange에 전달된 메세지가 어떤 Queue에 저장되어야 하는지 정의한다.

AMQP는 네트워크에 문제가 발생하거나 요청을 처리하지 못했을 경우를 대비하여 두 가지 수신 확인 모델을 지닌다.

  1. Consumer가 메세지를 받으면 브로커에게 통지하고, 브로커는 통지를 받았을 때만 Queue에서 해당 메세지를 제거한다.
  2. 브로커가 메세지를 전달하면 자동으로 삭제한다.

2-3. AMQP의 표준 Exchange 타입 [ 출처 ]

표준 Exchange 타입은 다음과 같이 나뉜다.

  • Direct Exchange: Exchange로 수신된 메세지의 routing key와 Queue의 Binding key가 정확히 매칭되는 Queue로 전달된다.

Direct Exchange

  • Fanout Exchange: Exchange와 매칭된 모든 Queue에 메세지를 전달한다. 1:N 관계로 메세지를 브로드캐스트한다.
  • Topic Exchange: Direct Exchange와 유사하다. 다만, routing key를 사용하지 않고, Wildcard를 사용한다. 하나의 메세지는 Wildcard에 부합하는 하나 혹은 여러 개의 Queue로 전달된다.

Topic Exchange

  • Headers Exchange: routing key 대신 헤더 속성을 통해 라우팅된다. x-match 인자에 따라 다르게 동작한다. x-match: all 인 경우, arguement의 모든 key-value가 헤더의 key-value와 같을 때 binding 하고 / x-math: any인 경우, arguement의 key-value 중 하나라도 헤더의 key-value와 같을 때 binding 한다.

Headers Exchange

만약 하나의 Queue에 여러 Consumer가 존재할 경우, Queue는 디폴트로 Round-Robin 방식으로 메세지를 분배한다. 만약 홀수 번 째 메세지의 처리 시간과 짝수 번째의 메세지 처리 시간의 차이가 크다면 계속해서 하나의 Consumer만 일하게 될 수도 있다. 이를 방지하기 위해 Prefetch count 옵션을 1로 설정하여, 하나의 메세지가 처리되기 전까지 새로운 메세지를 받지 않게 하여 작업을 분산시키기도 한다.

 

2-4. AMQP의 구현

AMQP를 구현하는 다양한 브로커가 존재한다. 가장 대표적인 RabbitMQ부터, Apache Kafka, ZeroMQ, ActiveMQ 등이 있지만, 본 글에서는 RabbitMQ에 대해서만 다루고자 한다.

 

3. RabbitMQ

RabbitMQ는 AMQP를 구현하는 오픈소스 메세지 브로커이다. 사용하는 케이스는 주로 (1) 요청을 많은 사용자에게 전달할 때, (2) 요청에 대한 처리 시간이 길 때, (3) 많은 작업이 요청되어 처리를 해야할 때이다.

 

3-1. RabbitMQ의 장점

  1. RabbitMQ는 저명한 오픈 소스이다.
    1. 신뢰성과 안정성이 있고, 상업적인 지원이 가능하다.
  2. 유연한 라우팅이 가능하다. ( 플러그인을 이용하여 복잡한 라우팅이 가능하다 )
  3. 클러스터링 ( 로컬 네트워크에 있는 여러 RabbitMQ 서버를 논리적으로 클러스터링할 수 있음 ) 이 지원된다.
  4. RabbitMQ는 관리자 페이지 및 모니터링 페이지를 제공하여 관리의 편의성을 제공한다.
  5. 거의 모든 언어와 운영 체제에서 사용 가능하다.

 

3-2. RabbitMQ의 단점

  1. 유연한 라우팅이 가능하긴 하지만, 이를 올바르게 구성하고 관리하는 것은 어렵다.
  2. 클러스터링도 가능하긴 하지만, 이를 올바르게 구성하고 관리하는 것은 어렵다.
  3. RabbitMQ는 메세지를 메모리에 유지하는 방식으로 동작하기에, 큰 메세지 부하를 처리할 때 메모리 사용량이 높아질 수 있다.
  4. RabbitMQ는 클러스터링을 통한 확장을 지원하고 있지만, 대규모 메세지 부하에 대한 수평 확장이 다른 시스템에 비해 제한적일 수 있다.

 

3-3. RabbitMQ의 Exchange 속성

  1. Name: Exchange 이름
  2. Type: 메세지 전달 방식 ( Direct / Fanout / Topic / Header )
  3. Durability: 브로커가 재시작될 때 남아있을지 여부
    1. Durable: 브로커가 재시작되어도 디스크에 저장되어 남아있음
    2. Transient: 브로커가 재시작되면 사라짐
  4. Auto-delete: 마지막 Queue 연결이 해제될 때, 삭제될지 여부

 

3-4. RabbitMQ의 Queue 속성

  1. Name: Queue 이름
  2. Durability: 브로커가 재시작될 때 남아있을지 여부
    1. Durable: 브로커가 재시작되어도 디스크에 저장되어 남아있음
    2. Transient: 브로커가 재시작되면 사라짐
  3. Auto-delete: 마지막 Consumer가 consume을 끝낼 경우, 자동 삭제 여부
  4. Argument: 메세지 TTL, Max Length 같은 추가 기능

 

 

'Protocol' 카테고리의 다른 글

Server Sent Events ( SSE )  (0) 2023.09.17