MQ

이번 프로젝트를 진행하면서 MQ와 관련된 내용들이 많이 있어 정리하려고 합니다.

 

MQ(Message Queue)는 메시지를 큐에 저장하고, 필요한 시점에 꺼내어 처리할 수 있도록 해주는 시스템으로, 메시지를 효율적으로 주고받기 위한 MOM(Message-Oriented Middleware, 메시지 지향 미들웨어)의 한 종류입니다.

 

메시지 생성자(Producer)와 메시지 수신자(Consumer) 사이에서 중간에서 메시지를 받아 임시로 보관하고, 다시 전달하는 역할을 하므로 Broker라고도 불립니다.

 

MQ를 사용하는 이유

MQ를 사용하는 이유는 다음과 같습니다.

1. 데이터 유실 방지

기존 방식에서는 메시지를 직접 수신자(Consumer)에게 보내는 구조이기 때문에, 수신자가 꺼져 있거나 오류가 발생하면 메시지가 손실될 수 있습니다.

하지만 MQ는 중간에 Broker가 메시지를 받아 Queue에 저장하기 때문에, 수신자가 잠시 중단되어 있어도 나중에 다시 연결되었을 때 누락 없이 모든 메시지를 순차적으로 수신할 수 있습니다.

예시: IoT 센서가 주기적으로 데이터를 보내는데 서버가 재시작되는 상황에서도 데이터를 놓치지 않고 수신 가능.


2. 비동기 처리로 시스템 효율 향상

Producer와 Consumer가 직접 연결되어 있으면, Producer는 Consumer가 응답할 때까지 기다려야 합니다.
하지만 MQ를 사용하면 Producer는 메시지만 큐에 넣고 바로 다음 작업을 처리할 수 있기 때문에, 처리 속도가 빨라지고 시스템이 훨씬 유연해집니다.

예시: 사용자가 웹사이트에서 주문을 완료하면, 주문 정보는 MQ를 통해 백엔드 시스템으로 전달되고, 결제/배송 처리는 비동기적으로 진행됨.


3. 서비스 간 결합도 감소 (Decoupling)

Producer는 메시지를 큐에 넣기만 하면 되고, 누가 언제 어떻게 처리할지는 몰라도 됩니다.
Consumer는 큐에 들어온 메시지를 처리할 뿐, 누가 메시지를 보냈는지는 몰라도 됩니다.
이런 구조는 서로 독립적인 서비스 개발과 유지보수에 매우 유리합니다.

예시: 이메일 전송, SMS 알림, 푸시 메시지 등 다양한 알림 서비스가 동일한 메시지를 각각 처리할 수 있음.


4. 확장성과 유연한 메시지 처리

MQ를 사용하면 Consumer 수를 자유롭게 늘릴 수 있어, 많은 양의 메시지가 동시에 들어와도 여러 Consumer가 병렬로 처리할 수 있습니다.
또한 우선순위에 따라 다른 큐로 나누거나, 지연 처리(Delayed Queue) 등의 전략도 가능합니다.

예시: 대규모 이벤트 등록 시 수천 개의 요청을 동시에 받아도, Worker 수를 조절해 탄력적으로 처리 가능.


5. 재시도 및 장애 복구 지원

Consumer가 일시적으로 장애가 나도 MQ는 메시지를 큐에 보관하고 재시도할 수 있습니다.
또한 메시지 처리가 실패하면 다시 큐에 넣어 재전송하는 등의 정책 설정도 가능합니다.

 

MQ 프로토콜

MQ는 단순한 메시지 송수신 구조가 아니라, 중간에 메시지를 전달하고 분배하는 역할을 하는 Broker가 개입합니다.

 

이 구조에서는 메시지를 어떤 기준으로 어떤 Queue에 전달할지를 정해야 하며, 이를 위해 명확한 메시징 프로토콜과 구성 요소가 필요합니다.


기본 용어 정리

  • Producer (Publisher)
    메시지를 생성하여 MQ에 전송하는 주체입니다.
  • Consumer (Subscriber)
    메시지를 MQ에서 받아서 처리하는 주체입니다. 예: 결제 처리 서비스
  • Queue
    메시지를 임시로 저장하는 공간입니다. 메시지는 여기서 대기하다가 Consumer가 처리합니다.
  • Exchange
    메시지를 받아 어떤 Queue에 보낼지를 결정하는 라우팅 역할을 합니다.
    (중간 관리자 느낌이라고 보면 됩니다.)
  • Binding
    Exchange와 Queue를 연결할 때 사용하는 규칙입니다.
    어떤 조건의 메시지를 어떤 Queue에 보낼지를 정합니다.
  • routing_key
    Producer가 메시지를 보낼 때 함께 지정하는 "주소" 같은 역할입니다.
    Exchange는 이 값을 기준으로 메시지를 라우팅합니다.

Exchange의 종류

1. Direct Exchange

  • 정확히 일치하는 routing_key를 가진 Queue에만 메시지를 전달합니다.
  • 마치 편지 봉투에 '서울시 강남구'라고 써 있으면, 정확히 그 주소의 집으로만 가는 느낌입니다.

🔹 예시:

routing_key = "email.send" 
Binding Key = "email.send"
→ 전달됨
routing_key = "email.update" 
Binding Key = "email.send" 
→ 전달 안 됨

2. Fanout Exchange

  • 모든 연결된 Queue에 무조건 전달합니다.
  • routing_key는 무시됩니다.
  • 마치 방송국이 전파를 퍼뜨리는 느낌입니다.

🔹 예시:

  • 알림 시스템에서 "새 게시물 생성됨" 이벤트를 보내면:
    • 이메일 알림
    • 앱 푸시 알림
    • 슬랙 메시지
      이 3개 Queue에 동시에 메시지 전달됨.

3. Topic Exchange

  • 패턴 기반으로 routing_key와 Binding Key를 비교하여 메시지를 라우팅합니다.
  • 와일드카드(*, #)를 사용할 수 있어 유연한 라우팅이 가능합니다.
와일드카드의미
* 정확히 하나의 단어와 일치
# 0개 이상의 단어와 일치

🔹 예시:

  • Binding Key: sensor.*
    • routing_key =  sensor.temp  → ✅ 전달됨
    • routing_key =  sensor.humidity   → ✅ 전달됨
    • routing_key =   sensor.temp.rom1  → ❌ 전달 안 됨
  • Binding Key: sensor.#
    • routing_key =  sensor  → ✅ 전달됨
    • routing_key =  sensor.temp  → ✅ 전달됨
    • routing_key =  sensor.temp.rom1  → ✅ 전달됨

4. Headers Exchange

  • routing_key를 사용하지 않고, 메시지에 포함된 헤더 값을 기준으로 메시지를 라우팅합니다.
  • 조건은 헤더에 지정된 키-값 쌍이 Queue의 Binding 조건과 일치해야 합니다.
  • 보다 복잡하거나 유연한 조건 기반 라우팅에 유리합니다.

🔹 예시:

 

메시지 헤더:

{
  "type": "email",
  "priority": "high"
}

 

Queue A의 Binding 조건:

{ 
  "x-match": "all", 
  "type": "email", 
  "priority": "high" 
}

→ 조건이 모두 일치하므로 메시지 전달됨.

 x-match: any 로 설정하면 조건 중 하나만 일치해도 메시지가 전달됩니다.


대표적인 MQ 프로토콜 및 시스템

AMQP (Advanced Message Queuing Protocol)

  • 다양한 시스템 간의 메시지를 안정적으로 전달하기 위한 프로토콜
  • RabbitMQ는 AMQP를 사용하는 대표적인 메시징 시스템

MQTT (Message Queuing Telemetry Transport)

  • 사물인터넷(IoT) 환경에서 많이 사용되는 경량 메시징 프로토콜
  • 낮은 대역폭과 낮은 전력 환경에서 효과적
  • Publish/Subscribe 구조를 채택
  • 대표적인 브로커: Mosquitto, HiveMQ 등

Kafka

  • 대용량 데이터 스트림 처리에 최적화된 분산 메시징 시스템
  • 메시지를 토픽(Topic) 단위로 분류하며, 로그 수집/분석, 실시간 데이터 처리에 자주 사용됨

NATS

  • 경량화된 메시지 브로커로, 빠른 속도와 단순한 구조가 장점
  • Microservices 간 통신에 적합
  • 대용량 처리에 적합함

마치며

MQ를 몰랐던 때에는 로그 손실에 대한 걱정을 많이 했었는데 이번 프로젝트를 맡게 되면서 좋은 시스템을 알게 되었습니다.

'Study' 카테고리의 다른 글

[RabbitMQ] 개념 및 사용법  (0) 2025.04.24
[Rack Tables] 설치  (5) 2024.12.24

+ Recent posts