20241205 TIL : RabbitMQ

MCS·2024년 12월 5일

TIL

목록 보기
19/45

오늘 학습한 내용

  • RabbitMQ
    • RabbitMQ의 역할
    • RabbitMQ의 구성 요소
    • RabbitMQ와 SAGA 패턴을 이용한 분산 트랜잭션

RabbitMQ

RabbitMQ는 메시지 브로커로, 데이터(메시지)를 생산자(프로듀서)로부터 소비자(컨슈머)에게 전달하는 중간 매개체이다.
메시지는 큐에 저장되며, 필요할 때 적절한 수신자에게 전달된다.
주로 MSA에서 서비스 간 비동기 통신을 위해 널리 사용된다.

RabbitMQ의 역할

  • 비동기 처리 : 데이터를 비동기적으로 처리하여 시스템의 응답성을 높임
  • 부하 분산 : 여러 소비자(컨슈머)에게 메시지를 분산시켜 시스템의 부하를 분산
  • 내결함성 : 메시지를 큐에 안전하게 저장해 시스템 장애 시 데이터 손실을 방지

장점

  • 신뢰성
    • 메시지 지속성 : RabbitMQ는 메시지를 디스크에 저장하여 시스템 장애 발생 시에도 메시지가 손실되지 않게 함
    • 확인 메커니즘 : 메시지가 성공적으로 소비자에게 전달되었는지 확인하는 ACK 메커니즘 지원
  • 유연성
    • 다양한 메시지 패턴 : 단일 소비자, 다중 소비자, 라운드 로빈, 팬아웃, 주제 기반 등 다양한 메시지 패턴을 지원
    • 프로토콜 지원 : 기본적으로 AMQP(Advanced Message Queuing Protocol)를 사용하지만, STOMP, MQTT 등 다양한 프로토콜도 지원
  • 확장성
    • 클러스터링 : 클러스터링을 통해 여러 노드로 구성된 환경에서 높은 가용성 및 부하분산 제공
    • 분산 아키텍처 : 페더레이션(Federation) 등을 사용하여 여러 RabbitMQ 인스턴스 간에 메시지를 전달함으로써 분산된 메시징 시스템을 구축 가능
  • 관리 및 모니터링
    • 관리 인터페이스 : 웹 기반 관리 인터페이스를 통해 큐, 익스체인지, 바인딩 등을 쉽게 관리할 수 있음
    • 플러그인 시스템 : 관리 플러그인, 모니터링 플러그인 등 다양한 플러그인을 통해 기능을 확장할 수 있음
  • 성능
    • 높은 처리량 : 적절히 구성된 RabbitMQ는 높은 메시지 처리량을 제공하여 대규모 애플리케이션에서도 효과적으로 사용할 수 있음

위 장점 외에도, 비동기 처리에서 오는 장점 또한 존재한다.
전자상거래 애플리케이션에서 주문 처리를 하는 시나리오를 예시로 들어 보자.

비동기 처리 시나리오
사용자가 주문 생성 -> 주문 데이터가 RabbitMQ 큐로 전송
RabbitMQ 큐 -> 주문 데이터를 보관하며 소비자를 기다림
소비자의 처리 -> 소비자가 큐에서 메시지를 가져와 결제 및 재고 확인 등의 작업을 수행

만약 동기 처리를 할 경우, 주문이 몰릴 경우에 먼저 들어온 주문이 처리될 때 까지 대기해야 한다. 즉 생산자가 소비자 작업이 완료된 후에야 다시 작업을 수행할 수 있다. 이는 주문이 많아질수록 처리 속도가 느려지는 문제가 생긴다.
RabbitMQ로 비동기 처리를 한다면 생산자는 소비자를 기다리지 않고 큐에 메시지를 보내므로, 병렬 처리를 통해 빠른 처리 속도를 가진다.

단점

  • 설정 및 운영 복잡성
    • 복잡한 설정 : RabbitMQ의 초기 설정이 다소 복잡할 수 있으며, 클러스터링 및 분산 환경에서는 더욱 많은 설정이 필요
    • 운영 관리 : 대규모 환경에서 RabbitMQ를 운영하고 관리하는 데 있어서 추가적인 노력이 필요
  • 성능 문제
    • 메시지 브로커 오버헤드 : RabbitMQ는 모든 메시지를 중앙 브로커를 통해 전달하므로 높은 트래픽 상황에서는 브로커의 오버헤드가 발생
    • 대규모 메시지 처리 : 매우 대규모의 메시지를 처리할 때 성능 저하가 발생할 수 있으며 적절한 클러스터링 및 최적화가 필요
  • 운영 비용
    • 리소스 소비 : RabbitMQ는 메모리와 CPU 자원을 많이 소비할 수 있어, 충분한 리소스를 제공해야 함
    • 모니터링 및 유지보수 : 지속적인 모니터링과 유지보수가 필요해 추가적인 인력 및 비용이 발생할 수 있음
  • 제한된 메시지 크기
    • 메시지 크기 제한: RabbitMQ는 매우 큰 메시지 처리에 제한이 있을 수 있으며, 대용량 파일 전송에는 적합하지 않음

RabbitMQ의 구성 요소

  • 메시지 : RabbitMQ를 통해 전달되는 데이터 단위이다. 앞서 언급한 비동기 처리 시나리오에서 주문 데이터가 이에 해당한다.
  • 프로듀서 : 메시지를 생성하고 RabbitMQ에 보내는 역할을 한다. 앞서 언급한 비동기 처리 시나리오에서 사용자가 주문 생성 시 주문 데이터를 RabbitMQ 큐로 전송하는 로직이 이에 해당한다.
  • 큐 : 메시지를 저장하는 장소로, 생산자가 메시지를 큐로 전송하면 보관하고 있다가 소비자에게 전달한다. 큐이므로 메시지를 FIFO로 처리한다.
  • 컨슈머 : 큐에서 메시지를 가져와 처리하는 역할을 한다. 비동기 처리 시나리오에서 큐에서 메시지를 가져와 결제 및 재고 확인 등의 작업을 수행하는 부분이 이에 해당한다.
  • 익스체인지 : 메시지를 적절한 큐로 라우팅하는 역할을 한다. 프로듀서는 실제로 메시지를 큐에 직접 보내지 않고 익스체인지에 보내며, 익스체인지에서 이를 적절한 큐로 보낸다.

AMQP

  • RabbitMQ는 기본적으로 AMQP(Advanced Message Queuing Protocol)를 사용한다.
  • AMQP는 메시지 브로커를 위한 프로토콜로, 메시지의 생성, 전송, 큐잉, 라우팅 등을 표준화하여 메시지 브로커가 상호 운용될 수 있게 한다.

AMPQ 주요 개념

  • 메시지(Message): 전송되는 데이터 단위
  • 큐(Queue): 메시지를 저장하고 전달하는 구조
  • 익스체인지(Exchange): 메시지를 큐로 라우팅하는 역할
  • 바인딩(Binding): 익스체인지와 큐를 연결하는 설정으로, 바인딩을 통해 메시지가 어느 큐로 전달될지 정의

익스체인지 유형

메시지 브로커가 메시지를 교환기에서 큐로 라우팅하는 방식으로, 익스체인지는 다양한 방식으로 메시지를 라우팅할 수 있다. 익스체인지는 주로 메시지의 라우팅 키와 바인딩 키 또는 패턴을 기반으로 작동합니다.

  • Dirty Exchange
    • 라우팅 키가 정확히 일치하는 큐로 메시지를 전달
    • 예) 라우팅 키가 error인 메시지는 error라는 바인딩 키를 가진 큐로 전달
  • Topic Exchange
    • 라우팅 키의 패턴을 사용하여 메시지를 전달
    • 패턴에는 와일드카드 * (단어 하나)와 # (0개 이상의 단어)가 사용됨
    • 예) 라우팅 키가 quick.orange.rabbit인 메시지는 바인딩 키가 .orange.인 큐로 전달
  • Fanout Exchange
    • 라우팅 키를 무시하고 교환기에 바인딩된 모든 큐로 메시지를 브로드캐스트
    • 모든 바인딩된 큐로 메시지가 전달됨
  • Headers Exchange
    • 라우팅 키 대신 메시지의 헤더를 기반으로 메시지를 라우팅
    • 헤더 값과 바인딩된 헤더 값이 일치하는 큐로 메시지를 전달

RabbitMQ와 SAGA 패턴을 이용한 분산 트랜잭션

SAGA 패턴을 간단하게 설명하면 다음과 같다.

  • 트랜잭션을 여러 단계로 나누어 처리하고, 각 단계가 독립적으로 커밋됨. 실패 시 보상 트랜잭션을 실행하여 상태를 롤백함.
    • 주문 생성 단계: 사용자가 주문을 생성
    • 결제 처리 단계: 결제 서비스가 주문 결제를 처리
    • 재고 감소 단계: 재고 서비스가 주문된 상품의 재고를 감소
    • 각 단계가 성공적으로 완료되면 다음 단계로 넘어가고, 실패하면 보상 트랜잭션을 통해 이전 단계에서 수행된 작업을 취소

RabbitMQ에서 사용하는 시나리오를 생각해 보면 다음과 같다.

시나리오
1. 사용자가 주문을 생성합니다.
2. RabbitMQ를 통해 메시지를 전달하여 각 단계(주문 생성, 결제 처리, 재고 감소)를 처리합니다.
3. 각 단계가 성공하면 다음 단계로 진행합니다.
4. 실패 시 보상 트랜잭션을 실행하여 이전 단계에서 수행된 작업을 취소합니다.

SAGA 패턴에서 RabbitMQ를 사용하는 것만 추가되었다. 이를 통해 분산 트랜잭션 구현이 가능하다.
다만 SAGA는 최종적 일관성(eventual consistency)을 보장하며, 동기적 트랜잭션의 강력한 일관성(ACID)을 보장하지는 않고, 보상 트랜잭션 로직을 모든 단계에 구현해야 하므로 복잡성이 증가하는 문제가 있다.

참고자료

https://pixx.tistory.com/335#%EC%82%AC%EC%9A%A9%20%EC%BD%94%EB%93%9C%20%EB%B0%8F%20%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-1

profile
백엔드를 잘 하고 싶은 사람

0개의 댓글