본문 바로가기

개발/Backend

[RabbitMQ] 메시지 브로커 시스템 이해하기

AI 분석 서버를 운영하게 되면 실시간으로 들어오는 요청을 처리해야 한다. 유저가 분석 요청을 하게 되면 서버는 데이터를 받아 처리하고 결과를 반환해야 한다. 그런데 분석 요청이 한두 건이 아니라 수백, 수천 건이 동시에 들어오게 된다면?

 

쉽게 예상할 수 있듯이 요청이 몰리면서 서버의 리소스가 한쪽에 치우친다거나, 특정 태스크가 오래 걸리면서 전체 요청의 지연으로 이어지게 된다거나 어쩌먼 특정 태스크의 분석이 실패하면 전체 작업이 중단되어 버릴 수 있다. 이때 문제를 해결하기 위한 도구가 바로 RabbitMQ다.

 

이번 글에서는 RabbitMQ가 무엇인지, 어떤 방식으로 구현이 되어 있는지에 대해 정리하고자 한다.

글의 대부분은 각 컴포넌트에 대한 설명이 될 것이고, RabbitMQ를 사용하는 방법에 대해서는 다음 글에서부터 알아보고자 한다.

 

 

1. RabbitMQ 주요 개념

RabbitMQ는 메시지 브로커로, 데이터를 Producer에서 Consumer로 전달하는 중재자 역할을 한다. 요청에 포함되는 메시지를 직접 주고받는 것이 아니라, 중간에 메시지를 처리하고 관리하는 시스템을 활용해 데이터를 효율적이고 안정적으로 만든다. RabbitMQ를 이해하려면 몇 가지 핵심 개념을 먼저 알아야 하는데, 아래의 순서로 하나씩 살펴보자.

 

1.1 프로듀서 (Producer)

프로듀서는 메시지를 생성하는 역할을 한다. 예를 들어, AI 분석 서버에서 새로운 분석 요청을 생성해 RabbitMQ로 전달하는 주체가 바로 프로듀서다. 프로듀서는 메시지를 익스체인지라는 컴포넌트로 보낸다.

1.2 익스체인지 (Exchange)

익스체인지는 메시지를 큐로 전달하기 전에 어떤 큐로 보낼지 결정하는 역할을 한다. 익스체인지에는 메시지 라우팅 방식을 정의하는 익스체인지 타입이 존재하며, 주요 타입은 아래와 같이 네가지 종류가 있다.

  • Exchange: 메시지가 routing key와 일치하는 큐로만 전달된다.
  • Fanout: 라우팅 키와 상관없이 익스체인지에 연결된 모든 큐로 메시지가 전달된다.
  • Topic: 라우팅 키를 와일드카드(*, #)로 매칭해 특정 조건을 만족하는 큐에만 메시지를 전달한다.
  • Headers: 메시지의 헤더 정보가 큐 조건과 일치할 때만 전달된다.

1.3 큐 (Queue)

큐는 메시지를 저장하는 버퍼다. 익스체인지로부터 메시지를 전달받아 컨슈머가 처리할 수 있을 때까지 대기 상태로 유지한다. 큐는 아래와 같은 특징을 가진다.

  • 내구성: 디스크에 메시지를 저장해 RabbitMQ가 재시작되더라도 메시지를 복구할 수 있다.
  • TTL (Time-to-Live): 메시지가 큐에서 머물 수 있는 시간을 제한한다.
  • Dead Letter Queue (DLQ): 처리되지 못한 메시지를 별도의 큐로 이동시킨다.

1.4 컨슈머 (Consumer)

컨슈머는 큐에서 메시지를 가져와 처리하는 역할을 한다. 컨슈머는 메시지를 처리한 후 Ack를 보낸다. Ack는 '이 메시지를 정상적으로 처리했다'는 신호이고, 이 신호를 통해 메시지가 큐에서 제거된다. 만약 Ack를 보내지 못하면 메시지는 다른 컨슈머에게 다시 전달된다.

1.5 바인딩 (Binding)

바인딩은 익스체인지와 큐를 연결하는 규칙이다. 프로듀서가 메시지를 익스체인지로 보낼 때, 바인딩을 통해 특정 조건에 맞는 큐로 메시지가 전달된다.

1.6 AMQP 프로토콜

RabbitMQ는 AMQP(Advanced Message Queuing Protocol)를 기반으로 동작한다. AMQP는 메시지 브로커와 클라이언트 간의 표준 통신 프로토콜로, 메시지 송수신 방식과 데이터 형식을 정의한다. 이를 통해 RabbitMQ는 다양한 언어와 플랫폼에서 일관되게 동작할 수 있다.

 

2. RabbitMQ의 작동 원리

주요 개념에 대해 어느정도 감을 잡았다면 이제 메시지가 처리되는 전체적인 흐름을 아래의 그림과 함께 이해해보자.

https://www.cloudamqp.com/

 

2.1 프로듀서가 메시지 생성 후, 익스체인지로 전달

 

RabbitMQ의 메시징 프로세스는 프로듀서에서 시작된다. 프로듀서는 아래의 정보를 포함한 메시지를 생성한다.

  • 메시지 본문: 전송할 데이터(예: 분석 요청의 구체적인 내용)
  • 라우팅 키: 메시지를 특정 큐로 라우팅하기 위한 키

프로듀서는 메시지를 익스체인지로 전달하며, 익스체인지는 라우팅 키나 바인딩 조건을 바탕으로 메시지를 적절한 큐로 전달한다. 이 단계에서는 프로듀서와 큐가 직접 연결되지 않기 때문에, 시스템의 결합도를 낮추는 데 큰 역할을 한다.

2.2 익스체인지가 메시지를 큐로 라우팅

익스체인지는 메시지를 큐에 분배하는 역할을 담당하여 익스체인지의 종류에 따라 기준에 맞는 큐로 분배한다.

2.3 큐에 메시지가 저장됨

메시지는 익스체인지를 거쳐 에 저장된다. 큐는 메시지를 안전하게 보관하며, 컨슈머가 이를 처리할 준비가 될 때까지 기다린다. 

2.4 컨슈머가 큐에서 메시지를 처리

컨슈머는 큐에서 메시지를 가져가 필요한 작업을 수행한다. 이 과정은 RabbitMQ의 Ack 메커니즘을 통해 안정적으로 관리되는데, 아래의 과정으로 진행된다.

  1. 컨슈머가 큐에서 메시지를 수신한다
  2. 메시지 처리가 성공적으로 완료되면 Ack를 RabbitMQ에 보낸다 (Ack를 수신한 RabbitMQ는 해당 메시지를 큐에서 제거한다)
  3. 메시지 처리가 실패하거나 컨슈머가 Ack를 보내지 않으면 메시지는 다시 큐로 돌아가 다른 컨슈머에게 전달된다(Requeue)

2.5 Dead Letter Queue(DLQ)

위의 그림에는 표현이 되어있진 않지만, 컨슈머가 메시지를 여러 번 처리하지 못하거나 TTL이 만료된 경우, 메시지는 Dead Letter Queue로 이동한다. DLQ는 실패한 메시지를 별도로 관리하여 문제를 분석할 수 있게 한다.

 

 

3. 나가며

이번 글에서는 RabbitMQ의 기본 개념과 작동 원리에 대해 이해해보았다. 다음 글에서는 RabbitMQ를 직접 실행하고, 실제 메시지를 발행해보면서 그 과정을 따라가보며 메시지가 전달되는 전 과정에 대해 알아볼 것이다.