ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RabbitMQ란?
    서버 2020. 7. 26. 17:05

    RabbitMQ는 AMQP 프로토콜을 구현한 메시지 브로커입니다. 생산자에게 메시지를 받아 소비자에게 전달해주는 서비스로 시스템 간 메시지를 전달해주는 오픈소스 메시지 브로커 소프트웨어입니다.

    AMQP란?

    AMQP란 Advanced Message Queueing Protocol의 줄임말로 MQ의 오픈소스에 기반한 표준 프로토콜을 의미합니다. AMQP는 마지막 P(rotocol)에서 보는 것과 같이 프로토콜을 의미하기 때문에 이 것을 사용한 가장 유명한 소프트웨어는 RabbitMQ라 볼 수 있습니다.


    AMQP를 구성하는 요소는 Exchange, Queue, Binding이 있습니다.

    Exchange

    Exchange는 생산자로부터 수신한 메시지를 적절한 큐나 다른 exchange로 분배하는 라우터의 기능을 합니다. Exchange는 수신한 메시지를 분배하기 위해 Exchange Type이라 하는 라우팅 알고리즘을 사용합니다. 브로커는 여러개의 Exchange Type 인스턴스를 가질 수 있습니다.

    Exchange Type을 아래의 Binding과 혼동할 수 있는데 Exchange Type은 받은 메시지를 어떤 방법으로 라우팅할 지 결정하는 것이고 Binding은 이러한 방법으로 결정된 메시지를 어느 Queue에 전달할 지 결정하는 라우팅 테이블입니다.

    예를 들어, 주소 정보를 받는 브로커가 존재하면 해당 주소 정보의 시, 도를 보고 Queue를 결정하는 방식을 Exchange Type이라 하고 서울은 1번 Queue, 인천은 2번 Queue 등과 같이 큐를 결정하는 것이 Binding입니다.

    Queue

    메모리나 디스크에 메시지를 저장하고, 그것을 소비자에게 전달하는 역할을 합니다.

    Binding

    Exchange와 Queue와의 관계를 정의한 일종의 라우팅 테이블입니다. 동일한 Queue가 여러 개의 Exchange에 Binding 될 수도 있고 단일 Exchange에 여러 개의 큐가 Binding 될 수도 있습니다.

    Standard Exchange Type

    Exchange Type은 메시지를 어떤 방법으로 라우팅할지 결정하는 알고리즘입니다. AMQP에서는 Standard Exchange Type으로 라우팅 키에 기반한 라우팅 알고리즘과 key-value 헤더에 기반한 1개 유형의 Exchange Type을 정의해야 합니다.

    Direct Exchange

    메시지의 라우팅 키를 기반으로 1:N으로 Queue에 매칭시키는 방법입니다.

    Topic Exchange

    와일드카드를 이용해서 메시지를 Queue에 매칭시키는 방법입니다. 

    Fanout Exchange

    모든 메시지를 Queue에 매칭하는 방법입니다.

    Headers Exchange

    key-value로 정의된 헤더에 의해 메시지를 Queue에 매칭시키는 방법입니다. x-match라는 argument로 헤더를 어떤식으로 해석하고 매칭시킬지 결정하는데, x-match가 all이면 모든 조건을 충족시켜야 한다는 것이고(AND), any이면 최소 1개의 조건만 충족시키면 된다는 의미입니다.(OR)

    RabbitMQ

    RabbitMQ는 AMQP를 기반으로 둔 소프트웨어이기 때문에 위에서 설명한 내용을 그대로 따라갑니다. 

    dispatching

    만약 여러 소비자가 1개의 Queue를 바라보고 있다면 RabbitMQ에서는 Round-robin을 사용해 메시지를 균등하게 분배합니다. 즉, 중복 처리를 방지하기 위해 첫 번째 메시지는 소비자 1에게 전달하고 두 번째 메시지는 소비자 1이 아닌 소비자 2에게 전달합니다. 소비자 뿐만 아니라 여러 생산자도 같은 Queue에 메시지를 전달 할 수 있습니다. 이러한 특성으로 메시지를 받아 처리하는 프로그램의 수평 확장이 가능합니다. 

    Fair dispatching

    만약 소비자는 2개만 존재하고 홀수 번째의 메시지의 크기는 항상 크고 짝수 번째 메시지는 항상 작다면 Round-robin 알고리즘을 사용해서 메시지 분배를 해도 공평하게 소비자에게 전달되지 않습니다. 이러한 이유로 지연이 발생한 소비자에는 메시지를 전달하지 않도록 prefetch count라는 개념을 사용합니다. prefetch count가 1로 설정되어 있다면 소비자로부터 act을 받지 못한 메시지가 1개라도 있으면 해당 소비자에 메시지를 전달하지 않습니다. 즉, prefetch count는 소비자에게 동시에 전달되는 메시지의 양입니다.

    소비자 서버가 죽었을 경우

    Queue는 소비자에게 메시지를 전달한 후 ACK을 받았을 때, 해당 메시지를 dequeue합니다. 소비자가 ACK을 Queue에 전달하지 못하는 경우는 받은 메시지가 너무 커 아직 처리 중이거나 소비자 서버가 죽었을 때입니다. RabbitMQ에서는 ACK을 받지 못한 메시지의 경우, 대기를 하고 있다가 전달한 소비자 서버의 상태를 확인한 후, Disconnected와 같은 신호를 받았을 경우 해당 소비자를 제외하고 다른 소비자에게 동일한 메시지를 전달합니다.

    Message Durability

    만약 메시지를 Queue에 넣은 다음 소비자에게 전달하기 전에 RabbitMQ 서버가 죽는다면 Queue는 메모리에 데이터를 쓰는 형식이므로 모든 데이터가 소멸하게 됩니다. 이러한 문제를 해결하기 위해 영속성이란 개념을 가지고 있습니다. 

    message durability는 메시지가 Queue에 저장될 때, disk의 파일에도 동시에 저장하는 방법입니다. 해당 방법을 사용하면 서버가 죽었을 때, Queue의 데이터가 어느 정도 복구가 되지만 메시지가 disk의 파일에 쓰는 도중에 서버가 죽는 경우도 있어서 일부 데이터의 소실이 발생할 수 있습니다.

    댓글