ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Rabbit MQ란?
    Infra 2021. 7. 8. 15:38

     

    RabbitMQ의 정의


    RabbitMQ는 AMQP(Advanced Message Queueing Protocol)을 구현한 오픈소스 메세지 브로커(중개자)이다. 간단히 말해서 Rabbit MQ는 데이터를 일단 어딘가에 쌓아두고 나중에 비동기적으로 적절한 처리를 하고 싶은 경우를 위한 데이터 저장소이다.

     

     

     

    RabbitMQ의 활용 예시


    실생활에서 예를 들어보자. 당장 개발해야 할 우선순위가 높은 작업들이 있는데 다른 직원들이 운영 업무 처리를 요청해 온다면, "업무 내용을 분류해서 메신저로 보내주시면 처리 후에 결과 알려드리겠습니다." 라고 하면 된다. 이 때의 메신저가 바로 RabbitMQ라고 할 수 있다.

     

     

     

    AMQP와 RabbitMQ


    RabbitMQ는 AMQP를 구현한다. 제타위키 AMQP에 따르면, AMQP를 구현하는 메세지 브로커의 종류로는 Apach Qpid, Apach ActiveMQ, RabbitMQ가 있다. 이 브로커들은 모두 AMQP를 구현하기 때문에, 사용법이 거의 비슷할 것이다. 그나저나 RabbitMQ에서 Rabbit은 왜 붙어진걸까? 나무위키 RabbitMQ 따르면, Rabbit Technologies 라는 단체에서 개발해서 그렇다고 한다. 번역이 맞으려나 모르겠다. 아무튼 AMQP를 알면 RabbitMQ가 어떤 기능을 제공하는지 알 수 있다. 그리고 RabbitMQ는 AMQP를 구현했기 때문에 이 프로토콜을 사용할 수 있다면 어떤 어플리케이션도 RabbitMQ를 사용하여 메세지를 Publish하거나 Consume할 수 있다.

     

     

     

    AMQP의 특징


    AMQP는 위 이미지와 같이 구성되어 있다. 위에 설명했던 예시로 설명해보자면 Publisher는 '다른 직원들', Exchange는 '분류해서', binding은 '보내주시면', Queue는 '메신저', Consumer는 '처리 후에 알려드리겠습니다'로 매칭시켜볼 수 있겠다. 

     

    AMQP의 각 영역을 자세히 살펴보자.

     

    Publisher

    Publisher는 Queue에 넣을 메세지를 생성하는 주체이다. 생성된 메세지는 최종적으로 특정 Queue에 넣어져야 한다. 하지만 Publisher는 메세지를 Queue에 직접 넣을 수 없다. 바로 뒤에 나올 Exchange만이 Queue에 메세지를 넣을 수 있다. 따라서 Publisher가 생성한 메세지는 먼저 Exchange에게 전달된다. 이 때 Publisher는 메세지가 담기게 될 Queue의 key값도 같이 전달한다. Queue 각각은 자신의 key(routing key라고도 함)를 소유하고 있다.

     

    Exchange

    Exchange는 우선 수신한 key에 특정한 알고리즘 중 하나를 적용하여 메세지가 담기게 될 Queue를 찾는다. 이를 binding이라고 한다. 그 다음 Publisher로부터 수신한 메세지를 이 Queue로 분배한다. 이를 routing이라고 한다. 그리고 Exchange가 사용하는 특정한 알고리즘(Exchange Type)들은 아래와 같다. 각 Exchange는 아래 알고리즘 중에 하나를 속성으로 갖는다.

     

    Exchange Type 설명
    fanout - 모든 Queue에 메세지를 전달한다.
    - routing key에 대해 연산할 필요가 없기 때문에 성능적인 이점이 있다.
    - broad cast에 적합하다.
    direct - Publisher가 전달한 key와 routing key가 일치하는 Queue에만 메세지를 전달한다.
    - 매우 단순하다.
    - unicast cast에 적합하다.
    topic - Publisher가 전달한 key가 routing key 패턴과 일치하는 Queue에만 메세지를 전달한다.
    - multi cast에 적합하다.
    header - 메세지 속성 내의 headers 테이블을 사용하여 특정한 규칙에 맞는 Queue에만 메세지를 전달한다.
    - routing key를 사용하는 것보다 쉽다.
    - multi cast에 적합하다.
    - https://www.rabbitmq.com/tutorials/amqp-concepts.html 참고

    Exchange 역시 여러개 존재할 수 있고 Publisher는 원하는 Type의 Exchange를 선택하여 메세지 전송을 요청할 수 있다.

     

    Queue

    Queue는 여러개 존재할 수 있다. 각 Queue는 routing key 혹은 routing key pattern을 갖는다. 

     

    Consumer

    Consumer는 Queue에 쌓인 메세지를 꺼내서 적절하게 처리한다. 이때 가장 먼저 쌓인 메세지부터 꺼내어진다. Consumer가 꺼내어진 메세지를 성공적으로 처리하면 Queue로 ack를 전달한다. ack는 '나 메세지 잘 처리했어!'라는 응답이다. 이 응답이 와야만 Queue는 메세지를 삭제한다.

     

     

     

    Prefetch Count


    하나의 Queue를 여러 Consumer가 listen 하고 있을 때, AMQP 브로커는 round robin 방식을 사용하여 각 Consumer에게 메세지를 균등하게 분배한다. 하지만 예를들어 매 짝수번째 메세지는 데이터의 크기가 크고 매 홀수번째 메세지는 데이터의 크기가 작으면 메세지가 각 Consumer에게 공평하게 분배되지가 않을 수 있다. 따라서 크기가 큰 데이터를 처리하느라 새로운 메세지를 받을 준비가 안된 busy Consumer가 있다면 다른 idle Consumer에게 메세지를 전달하게 된다. 이를 위해 Prefetch Count라는 개념을 사용한다.

     

    Prefetch란 '하나의 Consumer가 처리할 수 있는 메세지 양' 이라고 볼 수 있는데, prefetch를 1로 설정해놓으면 Cosumer로부터 ack가 최소한 1개 이상 전달되어야 해당 Consumer로 메세지 전달을 재개한다. prefetch가 없다면 ack의 전달과 상관없이 기회의 평등(?) 처럼 계속 메세지를 각 Consumer들에게 공평하게 전달할 것이다. 이처럼 prefetch 설정을 통해서 처리 속도가 늦은 Consumer에는 메세지 전달 순서를 건너띄게 할 수 있다. 

     

     

     

    Message와 Queue 보존


    RabbitMQ가 종료되면 Queue와 안에있는 message는 모두 제거된다. 하지만 Queue를 선언할 때 durable 속성을 true로 설정하면 RabbitMQ가 종료된 후 다시 시작될 때 해당 Queue는 다시 자동으로 생성된다. 하지만 이렇게 해도 Queue 내부의 메세지는 여전히 삭제된다. 이를 방지하려면 Publisher가 message를 Exchange로 보낼 때 persistent 속성을 부여하면 된다. 그러면 메세지도 다시 생성될 것이다.

     

     

     

    Queue의 장점


    위 특징들을 통해 알 수 있는 Queue의 장점은 다음과 같다.

    • 비동기(Asynchronous): 요청된 작업을 Queue에 넣어두고, 급한 다른 작업부터 처리할 수 있다.
    • 비동조(Decoupling): 주 애플리케이션과의 의존성을 분리할 수 있다.
    • 과잉(Redundancy): 실패할 경우 재실행 가능합니다.
    • 보증(Guarantees): Queue에 따로 적재된 작업들을 모니터링 할 수 있다.
    • 확장성(Scalable): 다양한 애플리케이션이 message를 생산할 수 있다.

    'Infra' 카테고리의 다른 글

    서버 확장 방법(스케일 아웃 vs 스케일 업)  (0) 2021.02.09
    Redis  (0) 2020.06.22

    댓글

Designed by Tistory.