BackEnd/RabbitMQ

[RabbitMQ] RabbitMQ 기본 개념

샤아이인 2023. 3. 12.

 

1. RabbitMQ의 기능과 장점

  • 오픈소스
    • Pivotal의 소프트웨어이며, Mozilla Public 라이선스로 배포되고 있다. erlang으로 작성된 RabbitMQ는 오픈소스의 유연함에 안정성까지 갖췄다고 한다.
  • 플랫폼과 업체 중립성
    • AMPQ(Advanced Message Queuing Protocol)스펙을 구현한 메시지 브로커 이다.
  • 경량성
    • 관리자 UI플러그인과 함께 코어 애플리케이션을 구동하는데 40MB 미만의 메모리만 사용한다.
    • 이후에 Queue에 메시지 양이 증가하면 메모리 사용량이 증가하게 된다.
  • 다양항 클라이언트 라이브러리
    • RabbitMQ는 다양한 언어와 운영체제, 환경에서 서로 데이터를 공유할 수 있는 유용한 다리 역할을 한다.
  • 유연한 성능과 안정성 절충 제어
    • 안정적인 메시지 전달과 메시지 처리량, 혹은 성능을 유연하게 제어할 수 있는 옵션을 제공한다.
    • 메시지를 배달하기전에 물리메모리에 저장할 수 있으며, 클러스터를 설정할 때 Queue를 고가용성으로 설정하여 여러 노드에 걸쳐 저장하므로 일부 서버 장애로 메시지가 손실되지 않도록 처리할 수 있다.
  • 대기 시간이 긴 네트워크 환경을 위한 플러그인
    • 대기시간이 짧은 네트워크 환경에서의 메시지 전달은 기본 코어 모듈로 제공하고, 인터넷과 같이 대기 시간이 긴 네트워크 간의 메시지 전달은 플러그인을 통해 제공한다.
    • RabbitMQ를 이용해 동일한 로컬상의 네트워크에 클러스터를 구성할 수 있고, Federation 플러그인으로 여러 데이터센터 간에 메시지를 공유할 수 있다.
  • 서드파티 플러그인
    • 예를 들어 RabbitMQ를 직접 사용해 메시지를 데이터베이스에 직접 저장하는 서드파티 플러그인도 사용 가능하다.
  • 보안 계층
    • 클라이언트의 접속은 SSL만으로 제한함으로써 안전하게 처리하고, 가상 호스트로 사용자 접근을 관리해 메시지와 리소스를 고수준으로 격리해서 처리하고 있다.

 

1 - 1) RabbitMQ와 erlang

erlang은 함수형 프로그래밍 언어로, 분산처리, 장애 허용, soft real-time system과 같이 99.999%의 가동시간을 요구하는 애플리케이션을 위해 설계되었다.

 

이러한 동시성 처리와 메시지 전달에 대한 설계는 RabbitMQ와 같은 메시지 브로커를 구현할 때의 장점이다.

다른 메시지 브로커가 클러스터링 기능을 추가하기 위해 직접 구현해야 한다면, RabbitMQ는 erlang의 process간 통신 (IPC)시스템을 사용하므로 클러스터링 기능을 간단하게 구현할 수 있다.

 

1 - 2) RabbitMQ와 AMQP

RabbitMQ는 상호운용성(Interoperability), 성능, 안정성을 중요한 목표로 개발되어 2007년에 처음 나왔을때는 AMQP 스펙을 구현한 최초의 메시지 브로커중 하나였다.

 

다른 메시지 브로커와 비교할때 RabbitMQ는 다양한 프로토콜과 플러그인을 제공하므로 멀티 프로토콜 애플리케이션 아키텍처에 좋은 선택이다.

 

AMQP를 구현한 RabbitMQ는 유연한 메시지 라우팅, 메시지 내구성 설정, 데이터센터 간의 통신 등 메시지 지향 아키텍처의 복잡한 요구 사항에 대한 벤더 중립적이며, 플랫폼 독립적인 솔루션이다.

 

2. 느슨하게 결합된 아키텍처의 장점

만약 어떤 게임서버에 로그인 할때 사용자의 접속시간을 업데이트 해야 한다고 해보자!
저장하고 있는 DB를 여러곳일수록 많은 DB에 쿼리를 날려 시간을 업데이트 해야하며, 이는 자연스럽게 사용자의 로그인 시간이 길어짐을 의미한다.

 

더 나아가, 중간에 하나의 DB에 문제가 생기게 된다면 당연히 로그인이 안되는 문제까지 발생해버린다!

이때 RabbitMQ와 같은 메시지 지향 미들웨어(MOM)를 사용하게 된다.

 

로그인 처리에서 DB업데이트 작업을 분리한 후에는, 로그인 처리 중 DB update를 기다리지 않아도 되므로 신속하게 로그인이 가능해졌다. 대신 업데이트에 필요한 정보들이 메시지로 각 DB에 독립적으로 전달된다.

1) 사용자가 로그인 하면 RabbitMQ에 메시지가 발행되고 애플리케이션은 즉시 인증된 회원 페이지로 이동한다.

2) RabbitMQ는 로그인 이벤트 메시지를 구독하고 있는 모든 소비자에게 발행한다.

3) 각 소비자는 독립적인 자신의 데이터베이스 작업을 수행한다.

 

2 - 1) 데이터베이스 쓰기 의존성 제거

데이터베이스와 강하게 결합된 애플리케이션은 DB서버가 transaction을 완료하고 응답할 때 까지 기다려야 한다. DB와 강하게 결합된 구조는 동기 sync 애플리케이션과 async 애플리케이션 모두에서 성능상의 병목이 발생할 가능성이 있다.

 

즉, DB서버가 느려지면 애플리케이션 서버도 같이 느려저 버린다.

 

애플리케이션과 데이터베이스의 의존성을 분리해서 강결합 구조를 약결합 구조로 변경할 때, 메시지 지향 미들웨어인 RabbitMQ는 데이터베이스에서 작업을 수행하기 전 데이터의 중개자 역할을 한다. Consumer는 RabbitMQ 서버에서 데이터를 가져와서 DB에 작업을 수행한다.

1) 약결합한 애플리케이션이 RabbitMQ에 메시지를 발행한다.

2) RabbiMQ는 구독하고 있는 consumer 애플리케이션에 메시지를 전달한다.

3) 메시지를 전달받은 consumer 애플리케이션은 DB 쓰기 작업을 위해 데이터베이스와 통신한다.

 

2 - 2) 새로운 기능 추가하기

이러한 약결합 구조에서는 데이터를 다른 용도로 사용할 수 있다.

원래 데이터베이스에 기록할 목적으로만 사용하는 데이터를 다른 목적으로 가공할 수 있다.

 

서로 다른 cosumer가 다르게 동작하면 된다!

1) 메시지를 발행하는 애플리케이션은 변경 사항 없이 이전과 같은 방식으로 RabbitMQ에 데이터를 발행한다.

2) 데이터베이스 쓰기 작업을 하는 소비자 애플리케이션은 이전과 같은 방식으로 동작한다.

3) 새로운 소비자 애플리케이션은 서드파티 클라우드 서비스에 동일한 데이터를 전달한다.

 

2 - 3) 데이터와 이벤트 복제

RabbitMQ는 데이터 센터간에 배포된 애플리케이션의 데이터 동기화와 데이터 전달을 위한 플러그인을 제공한다.

Federation 플러그인은 WAN 허용 오차 및 네트워크 단절을 고려해서 원격 RabbitMQ 인스턴스에 메시지를 전달한다.

Federation 플러그인을 통해 손쉽게 RabbitMQ서버 또는 클러스터를 구축할 수 있게되는 것 이다!

 

2 - 4) AMQ 모델

RabbitMQ의 강점과 유연함은 AMQP스펙으로부터 비롯된다.

HTTP, SMTP와 같은 프로토콜과 달리 AMQP 스펙은 네트워크 프로토콜의 정의 뿐 아니라 서버 측 서비스와 동작 방식도 정의하는데, AMQ(Advanced Message Queuing) 모델을 살펴보면 확인할 수 있다.

 

AMQ 모델은 메시지 라우팅 동작을 정의하는 메시지 브로커의 3가지 추상 컴포넌트를 정의한다.

  • exchange : 메시지 브로커에서 큐에 메시지를 전달하는 컴포넌트
  • queue : 메시지를 저장하는 디스크상이나 메모리상의 자료구조
  • binding : 익스체인지에 전달된 메시지가 어떤 큐에 저장돼야 하는지를 정의하는 컴포넌트

 

▶ Exchange

exchange는 RabbitMQ에서 메시지를 적절한 목적지로 전달하기 위해 필요한 첫 번째 입력 값으로, AMQ 모델이 정의하는 세 컴포넌트중 하나다.

 

exchange는 RabbitMQ로 전송한 메시지를 수신하고 메시지를 보낼 위치를 결정한다.

exchange는 메시지에 적용할 라우팅 동작을 정의하는데, 이는 일반적으로 메시지를 보낼 때 함께 전달한 데이터 속성을 검사하거나 메시지에 포함된 속성을 이용해 처리한다.

 

RabbitMQ에는 서로 다른 라우팅동작 방식을 처리하는 exchange들이 있다.

1) producer 애플리케이션이 RabbitMQ에 메시지를 전달한다

2) RabbitMQ가 메시지를 받고 exchange에 전달한다

3) exchange는 메시지를 AMQ모델의 다음 컴포넌트인 Queue에 전달한다.

 

▶ Queue

큐는 수신한 메시지를 저장하는 역할을 하며 메시지에 수행하는 작업을 정의하는 설정 정보가 있다.

큐의 설정 정보에는 메시지를 메모리에만 저장하거나, consumer에게 전달하기 전에  디스크에 보관하는지가 정의 돼있다.

 

▶ Binding

바인딩을 사용해서 큐와 익스체인지의 관계를 정의한다. RabbitMQ에서 바인딩 키(binding-key)는 exchange가 어떤 큐에 메시지를 전달해야 하는지를 의미한다.

 

특정 유형의 익스체인지는 지정한 큐 에만 메시지를 전달하도록 필터링 하기도 한다.

익스체인지에 메시지를 발행할 때 애플리케이션은 라우팅 키(routing-key) 속성을 사용한다. 라우팅 키는 때로는 큐의 이름이거나 의미적으로 메시지를 설명하는 문자열이다.

 

익스체인지는 적절하게 메시지를 큐로 전달하기 위해서 메시지의 라우팅 키를 바인딩 키에 맞춰서 평가한다.

즉, 바인딩 키는 큐를 익스체인지에 연결하고 라우팅 키를 평가하는 기준이 된다.

각 익스체인지의 유형마다 다르지만, 단순하게 사용한다면 라우팅 키는 큐의 이름이다.

RabbitMQ에서 각 익스체인지 유형은 서로 다른 방식으로 라우팅 키를 처리하는데, 특정 익스체인지는 단순히 라우팅 키의 이름이 동일한지 검사하고 또 다른 유형의 익스체인지는 라우팅 키에서 좀 더 복잡한 패턴을 추출해 검사한다. 메시지 속성에 정의한 다른 속성을 우선적으로 평가해 라우팅 키를 완전히 무시하는 익스체인지 유형도 있다.

 

추가로 exchange를 다른 exchage와도 연결할수도 있다!

댓글