쌩로그

RabbitMQ 개요와 비동기 아키텍처 본문

아키텍처 및 라이브러리/RabbitMQ

RabbitMQ 개요와 비동기 아키텍처

.쌩수. 2025. 1. 23. 14:10
반응형

목차

  1. 포스팅 개요
  2. 본론
     2-1. RabbitMQ의 개요 - 비동기 아키텍처 소개
     2-2. RabbitMQ 설치
     2-3. AMQP의 이해
     2-4. 주요 용어와 Exchange의 이해

1. 포스팅 개요

해당 포스팅은 인프런 코드 빌런님의 RabbitMQ를 이용한 비동기 아키텍처를 수강하며 정리하는 포스팅이다.

이번 파트는 Section 1 쉽게 이해하는 RabbitMQ 개요와 비동기 아키텍처 이다.

학습 레포는 https://github.com/SsangSoo/RabbitMQ- 이다.

(완강시 public으로 변환 예정)

2. 본론

2-1. RabbitMQ의 개요 - 비동기 아키텍처 소개

  • 2007년에 릴리즈되었다.
  • RabbitMQ는 얼랭(Erlang)으로 만들어진 메시지 전송 브로커 오픈소스이다.
    • 미들웨어이다.
  • 시스템 간 비동기 메시징을 가능하게 하여 서비스 간 통신을 안정적이고 효율적으로 처리할 수 있게 해준다
  • 플랫폼 중립적이며, 가볍고 다양한 언어들의 클라이언트 라이브러리를 제공하고, 유연한 성능과 안정성을 제공한다.
    • RabbitMQ 이전에는 각 벤더사마다 메세징 라이브러리가 있었다.
      • 예) JMS(Java Message Service)
    • 그렇지만, RabbitMQ가 등장함으로써 플랫폼 중립적이게 되었다.
  • 클러스터를 설정할 때 큐를 HA(High Available) 로 설정하여 여러 노드에 저장하므로서, 메시지 손실을 방지한다.
  • 또한 쉽게 새로운 기능을 추가할 수 있고,
  • Federation 플러그인을 통해 데이터 동기화다중 마스터 복제를 구성할 수 있다.
  • 최근 MSA 환경에서 가장 일반적으로 쓰이는 기술 중에 하나이며, 대량의 데이터 전송 시 발생 할 수 있는 과부하를 분산시키며, 비동기 처리와 지연이 필요한 작업을 효과적으로 관리 해줄 수 있다.

대표적인 도메인 활용 사례

  • EDAEvent-Driven Architecture)
    • 주문/결제/배송 등의 비즈니스 도메인을 이벤트 기반의 독립적인 도메인 모듈로 구성
  • 로그 및 모니터링
    • 로그 수집 및 준 실시간 처리 모니터링 시스템 구축
  • 채팅 및 알람
  • 비동기 데이터 처리
    • 대용량의 이미지나 비디오 처리에 효율적인 분산 시스템 구축 가능
  • 여러 디바이스의 요청 처리
    • IoT와 같은 멀티 디바이스 환경에서의 요청 처리

2-2. RabbitMQ 설치

https://iizz.tistory.com/403

위 블로그를 참고했다.

필자는 윈도우다.
공식문서 가서 exe 파일을 다운받고 실행하면 Erlang이 설치되어있지 않으면 알아서 Erlang을 설치하라는 페이지가 나오고 설치하면 된다. 그리고 다시 설치파일 재실행하면 된다.

Erlang이 설치되어있다면, 그냥 설치된다.

즉, Erlang을 다운받고, RabbitMQ를 설치해야 정상적으로 설치된다.

또한 C:\Program Files\RabbitMQ Server\rabbitmq_server-4.0.5\sbin 과 같이 경로를 path에 설정해줘야 한다.

참고로 설치가 되면 자동으로 실행된다.

서비스 탭에서 RabbitMQ를 중지시키고 아래의 명령어들을 쳐주자.
위의 블로그에서도 나온 내용이지만, 웹 관리 콘솔 플로그인을 다운 받아줘야 한다.
그렇게 해야 아래의 과정도 다 진행된다.
(그 외 3개는 선택사항)

실행하면 아래와 같이 나온다.
localhost:15672 로 접속

id/pw 는 guest/guest가 기본이다.

로그인하면 아래와 같이 나온다.

그리고 아래의 그림과 같이 Admin 탭에서 Add a user 탭을 들어가서 관리자 계정을 하나 생성한다.

admin / (비번자유) , 권한도 Admin 으로 설정하고, Add user 를 한다.
그리고 우측 상단 logout 후 다시 admin 계정으로 로그인한다.

또한 Admin 탭에 들어가서 Guest 를 클릭하여 아래의 Delete user 를 통해서 지우자.

2-3. AMQP의 이해

메세지큐를 사용하는 이유

  • 비동기 메시지를 사용하여 다른 응용프로그램 사이에 데이터를 송수신하기 위함.
  • 클라이언트에 대한 동기 처리병목의 요인이므로 비동기로 처리 해도 될 영역에 대해서는 큐를 통해 분리해서 처리한다.
  • 결국 분산환경에서 응용프로그램들을 분리하고 독립적으로 확장하기 위해서 사용하고 기능별로 모듈 구성이 용이하다 (Scalability)
  • 요청에 대한 응답을 기다릴 필요가 없기 때문에 각 영역의 역할만 신경쓰면 된다. 어플리케 이션 레벨에서 분리 할 수 있다. (Abstraction of concerned)
  • 데이터를 메모리 대신에 디스크에 저장하여 데이터 유실을 방지 (Reliability)
    • 즉시 처리하지 않아도 나중에 다시 처리가 가능하다.
    • 메시지 영구 저장, 메시지 확인, 장애 복구 메커니즘을 통해 메시지의 신뢰성을 보장한다.
  • 확장성
    • 여러 노드에 걸쳐 쉽게 확장할 수 있어 높은 가용성을 제공하며, 필요에 따라 메시지를 클러스터링하거나 페더레이션(federation) 방식으로 확장할 수 있다.
  • 유연성
    • 다양한 exchange 유형과 라우팅 규칙을 지원하여 메시지를 효과적으로 라우팅하고 관리할 수 있다.
    • 광범위한 프로토콜 지원
      • 기본적으로 AMQP를 사용하지만, STOMP, MQTT, HTTP 등을 포함한 다양한 프로토콜을 지원
    • 풍부한 클라이언트 라이브러리
      • Java, Python, Ruby, .NET 등 다양한 언어로 클라이 언트 라이브러리를 제공하여 다양한 애플리케이션에서 사용할 수 있다.

AMQP

Advanced Message Queing Protocol의 약자로, 흔히 알고 있는 MQ의 오픈소스에 기반한 표준 프로토콜을 의미한다.

여기서 말하는 one to one fanout의 경우 Fanout 익스체인지는 여러 큐에 메시지를 브로드캐스트하지만, 각 큐에 연결된 소비자는 한 명이므로 메시지는 각각의 큐에서 하나의 소비자에게만 전달되므로 1:1 방식의 메시지 소비를 뜻한다.

여러 소비자에게 동시에 메시지를 전달하되 각 메시지가 단일 소비자에게만 전달되도록 보장하고 싶은 경우를 의미한다고 보면 된다.

AMQP 특징

이전에도 상용화된 MQ 제품들은 많았지만, 한가지 문제가 있다면 대부분 플랫폼 종속적인 제품들이었기 때문에 서로 다른 이기종간에 메시지를 교환하기 위해서는 메시지 포멧 컨버전을 위한 메시지 브릿지를 이용하거나 (속도 저하 발생) 시스템 자체를 통일시켜야 하는 불편함과 비효율성이 있었다.

즉, AMQP의 목적은 서로 다른 시스템간에 (비용/기술/시간적인 측면에서) 최대한 효율적인 방법으로 메시지를 교환하기 위한 MQ 프로토콜로 아래와 같은 특징이 있다.

  • 모든 broker들은 똑같은 방식으로 동작할 것
  • 모든 client들은 똑같은 방식으로 동작할 것
  • 네트워크상으로 전송되는 명령어들의 표준화
  • 프로그래밍 언어 중립적

Routing Model Components

AMQP의 라우팅 모델은 아래와 같은 3개의 중요한 component 들로 구성된다.

  • Exchange
  • Queue
  • Binding

각 컴포넌트들을 아래와 같은 상세 기능들을 수행한다.

  • Exchange
    • Publisher로부터 수신한 메시지를 적절한 큐 또는 다른 exchange로 분배하는 라우터의 기능을 한다.
  • Queue
    • 일반적으로 알고 있는 큐이다. 메모리나 디스크에 메시지를 저장하고, 그것을 consumer에게 전달하는 역할을 한다.
  • Binding
    • exchange와 큐와의 관계를 정의한 일종의 라우팅 테이블이다.
    • 같은 큐가 여러 개의 exchange에 bind 될 수도 있고, 하나의 exchange에 여러 개의 큐가 binding 될 수 도 있다.

Routing Key

  • 라우팅 키는 발행된 메시지와 큐가 라우팅 테이블을 통해 매칭되는 키를 뜻한다.
  • Publisher, 혹은 producer로 칭하는 송신부에서 송신한 메시지 헤더에 포함되는 것으로 일종의 가상 주소라고 보면 된다.

2-4. 주요 용어와 Exchange의 이해

  • Producer (생산자)
    • 메시지를 생성하고 RabbitMQ에 전송하는 애플리케이션
    • Producer는 특정 Exchange에 메시지를 전송하고 Exchange는 메시지를 라우팅하여 큐에 배치
  • Exchange
    • Producer로 부터 받은 메시지를 큐에 전달
    • Exchange 유형
      • Direct
        • 특정 라우팅 키와 정확히 일치하는 큐에 메시지를 전송
      • Fanout
        • 모든 큐에 메시지를 브로드캐스트
      • Topic
        • 라우팅 키 패턴을 기반으로 메시지를 특정 큐에 전달
      • Headers
        • 메시지 헤더 속성에 따라 메시지를 라우팅 메시지가 Exchange로 전송될 때, Routing Key가 함께 전달
  • Routing Key
    • 메시지를 전송할 때 Producer가 Exchange에 전달하는 키
    • Exchange는 이 Routing Key를 참고하여 어떤 큐에 메시지를 전달할지 결정
  • Queue
    • 메시지를 일시적으로 저장하는 버퍼 역할
      • RabbitMQ의 큐는 FIFO(First In, First Out) 방식으로 동작하며, 메시지가 소비자에게 전달될 때까지 보관
      • 각 큐는 여러 Consumer가 구독(수신)할 수 있으며, 메시지는 큐에 들어온 순서대로 전달
      • 비동기적으로 동작하며, 여러 컨슈머가 동시에 메시지를 소비할 수 있다.
        • 하나의 메시지가 여러 소비자에게 중복으로 전달될 수는 없음
        • 동일한 메시지를 수신하려면 Fanout Exchange 방식으로 동작해야만 함.
  • Binding
    • exchange와 큐간의 관계를 정의
    • 바인딩은 메시지를 라우팅할 때 어떤 조건으로 큐에 보낼지 정의하고 이를 위해 binding key가 사용됨
    • Binding Key와 Routing Key가 일치하면 해당 큐로 메시지가 전달 (패턴 매칭 가능)
  • Consumer (소비자)
    • 큐에서 메시지를 가져와 처리하는 애플리케이션
    • RabbitMQ는 여러 소비자에게 메시지를 로드 밸런싱 할 수 있다.
    • Consumer는 큐에서 메시지를 받아 처리하면 메시지에 대한 확인(ACK, acknowledgment)을 브로커에 전송함
    • 확인을 보내지 않으면, 브로커는 메시지를 재전송하거나 설정한 다른 Consumer에게 전달할 수 있다.
  • Message Acknowledgment (메시지 확인)
    • 메시지가 성공적으로 처리되었음을 RabbitMQ에 알리는 과정
    • 만약 소비자가 메시지를 성공적으로 처리하지 못했다면, 메시지를 다시 큐에 넣어 다른 소비자가 처리하도록 할 수 있다.

이 과정을 간략히 도식화 하면 아래와 같다.

1. Producer가 메시지와 Routing Key를 Exchange에 전송. 
2. Exchange가 Routing Key를 사용해 Binding Key가 일치하는 큐에 메 시지를 라우팅. 
3. Consumer가 큐에서 메시지를 가져와 처리하고, 성공적으로 처리되었음을 a cknowledgment로 RabbitMQ에 알림.

추가로 알아야 할 용어

  • Prefetch Count (프리페치 카운트)
    • 소비자가 받을 수 있는 최대 메시지 수를 설정
    • 한 번에 많은 양의 메시지를 처리하지 않도록 하여 소비자의 성능 최적화를 한다.
  • Virtual Host (가상 호스트)
    • RabbitMQ 서버 내의 논리적인 구획으로, 메시지 큐, 익스체인지, 사용자 권한 등으로 구분한다.
    • 하나의 RabbitMQ 서버 내에 여러 개의 가상 호스트를 설정하여 서로 다른 애플리케이션의 메시지를 격리 할 수 있다.
  • Dead Letter Queue (DLQ)
    • 메시지가 처리되지 못하거나 유효 기간이 지난 경우 별도의 큐로 이동하는 구조도 설정할 수 있다.

Exchange 유형에 따른 처리 흐름

Direct Exchange

  • Direct Exchange는 메시지가 라우팅 키(Routing Key)에 따라 특정 큐로 하나씩 전달되는 방식

  • 메시지를 발행할 때 사용하는 라우팅 키와 동일한 키로 익스체인지에 바인딩 된 모든 큐에 메세지를 전달한다.

  • 해당 라우팅 키와 일치하는 큐에만 메시지가 전달되는 방식이기 때문에 Direct Exchange 라고 한다.

  • 활용

    • 메시지가 명확하게 특정 큐로 전달되어야 할 때.
    • 큐마다 고유한 라우팅 규칙을 적용하여 메시지를 분류해야 할 때.
  • 사용 예시 : 주문에 따른 상태 지시

    • 주문 상태별로 라우팅 키를 정의하고, 각 상태에 해당하는 큐가 메시지를 받는다.
    • 매핑이 정확하게 되는 한 개의 키만 있으니까 1:1로 가능할거 같지만, 하나의 라우팅 키에 대해 여러 큐가 바인딩될 수 있기 때문에 1:N 매칭이 가능하다.
  • 예시 업무

    • 주문 상태 처리
    • 결제 처리
    • 사용자 알림 시스템 등.

Topic Exchange

  • Topic Exchange는 라우팅 키를 패턴 기반으로 정의하여 메시지를 여러 큐에 유연하게 전달할 수 있는 방식이다.
  • 라우팅 키에 와일드카드(*, #) 매칭을 사용하여 더 복잡한 라우팅이 가능 하다.
    • 와일드카드 * 의 경우 하나의 단어를 대체 하는 의미로 log.info, log.warn, log.error 와 같은 패턴의 메시지를 수신 할 떼 log.*infowarn, error 를 다 수신하게 만들수 있다.
    • #의 경우 0개 이상의 단어를 대체하므로 app.order.success, app.payment.success 와 같은 라우팅 키를 #.success 로 다 수신할 수 있다.
  • 사용 예시
    • 동적이고 유연한 라우팅이 필요할 때(로그 수집 시스템, 이벤트 기반 모니터링 등)

Fanout Exchange

  • Fanout Exchange브로드캐스트 방식으로 메시지를 모든 바인딩된 큐에 전달한다.
  • 한 번의 메시지 발행으로 모든 큐가 동일한 메시지를 받는다.
  • 사용 예시
    • 이벤트가 발생하면 모든 서비스가 동일한 메시지를 받는 서비스에서 유용하다.
      • 시스템 점검 공지 등

Headers Exchange

  • 메시지의 속성(헤더)에 기반한 복잡한 라우팅이 필요할 때 사용
  • 사용 예시
    • 다국어 서비스, 고객의 등급별 혜택 알림.
      • 메시지 헤더에 language: "ko", language: "en" 등의 값을 설정하여 헤더 기반 라우팅을 수행한다.
      • language: "ko"로 설정된 메시지는 한국어 이메일 서비스에서 처리.
      • language: "en"으로 설정된 메시지는 영어 이메일 서비스에서 처리.

메시지 전송 단계별 프로세스

Producer - 라우팅 키 -> exchange - 바인딩 -> Queue

  • 메시지 송신 (Producer -> Broker)
    • Producer가 RabbitMQ Broker로 메시지를 송신
    • 이때 메시지는 큐에 저장되며, 익스체인지와 바인딩 설정에 따라 적절한 큐로 라우팅
  • 메시지 전달 (Broker -> Consumer)
    • Broker는 큐에 있는 메시지를 Consumer에게 전달.
    • Consumer는 큐에서 메시지를 가져가거나(Polling) 메시지를 푸시(Push) 받는 방식으로 수신
  • 메시지 확인(ACK) 또는 거절(NACK)
    • ACK
      • Consumer가 메시지를 성공적으로 처리한 후 Broker에ACKAcknowledgment) 를 전송.
      • 이 경우 Broker는 해당 메시지를 큐에서 제거하고 Producer에게 Message Acknowledged 응답을 전송
    • NACK
      • Consumer가 메시지 처리에 실패하거나 메시지를 거절할 경우 NACK(Negative Acknowledgment)을 전송.
      • NACK에는 메시지를 다시 큐로 보내야 할지(requeue) 또는 폐기해야 할지(discard) 설 정 가능
      • 재전송 요청 (Requeue)
        • 메시지를 다시 큐로 보내고 재처리할 수 있도록 설정
      • 폐기(Discard)
        • 메시지를 큐에서 제거하고, 폐기 처리
      • Consumer가 메시지를 NACK하면 Broker는 Producer에게 Message Rejected 응답 을 전송
  • Producer에 응답 (Message Acknowledged / Message Rejected)
    • Producer가 Publisher Confirms를 활성화한 경우, Broker는 ACK 또는 NACK 결과를 Producer에게 전송
    • ACK를 받은 경우 메시지가 성공적으로 소비된 것으로 간주되며, NACK를 받은 경우 Producer는 메시지 실패를 기록하거나 재전송한다.
728x90
Comments