개요
메시지 패턴은 분리된 서비스들 간 메시지를 활용해서 정보를 공유하는 아키텍처입니다.
서비스에서 변화가 발생하면 메시지를 게시하고 게시된 메시지는 소비자들이 비동기적으로 처리합니다.
즉, 각 서비스 간 느슨한 결합을 통해 확장성과 유연성이 향상됩니다.
이 글을 읽기 앞서, 동기와 비동기에 대해 이해하는 것을 추천드립니다.
https://growth-coder.tistory.com/341
동기 (Synchronous) vs 비동기 (Asynchronous)
개요이 글은 bytebytego의 동기 vs 비동기를 참고하여 작성했습니다. https://blog.bytebytego.com/p/synchronous-vs-asynchronous-communication Synchronous vs Asynchronous Communication: When to Use What?At some point, every system has to ma
growth-coder.tistory.com
주요 개념
- 생산자 (Producer) : 메시지를 생성하여 큐나 주제에 전달한다.
- 소비자 (Consumer) : 메시지를 가져와서 처리한다.
- 메시지 큐 (Message Queue) : 다른 서비스 간 메시지를 전달하기 위한 서비스.
- 메시지 브로커 (Message Broker) : 메시지 큐를 확장한 기술로 광범위한 전송과 라우팅을 담당.
메시지 전송 보장 방식 (Delivery Semantics)
- At most once : 메시지들은 한 번 전달되거나 아예 전달되지 않는다.
- At least once : 메시지들은 한 번 이상 전달되어야 한다.
- Exactly once : 메시지들은 오직 한 번 전달되어야 한다.
Queues

Queue 방식은 생산자가 메시지를 큐에 보내면 생산자는 큐에서 메시지를 가져와서 작업을 수행하는 방식입니다.
대형 마트의 계산대를 생각하면 쉽게 이해할 수 있습니다.
구매자(생산자)가 물건(메시지)을 계산하기 위해 줄을 서고 계산대(소비자)에서 순서대로 계산을 합니다.
대형 마트의 경우 계산대(소비자)를 여러 대 두어 계산해야 할 물건(메시지)가 많을 경우 병렬로 처리할 수 있습니다.
이 방식은 다음과 같은 특징을 갖습니다.
- 한 소비자가 큐에서 메시지를 가져오면 그 메시지는 다른 소비자가 가져올 수 없습니다.
즉, 같은 메시지가 여러 소비자에게 전달될 수 없습니다. - 먼저 들어온 메시지가 먼저 소비되는 선입선출 구조입니다.
- 소비자에서 장애가 발생하더라도 메시지를 나중에 처리할 수 있습니다.
- 어떠한 메시지가 계속해서 처리에 실패한 경우 이 메시지를 큐에서 삭제합니다.
queues 방식은 메시지가 딱 한 번 처리되어야 할 때 적합한 방식입니다.
- 백그라운드 작업 (이메일 시스템)
- 작업을 병렬로 처리해야 할 때
- 서비스에 부하가 걸릴 때
pub-sub

메시지를 여러 개의 소비자에게 전달할 때 사용되는 구조입니다.
앞서 배운 queues의 경우 하나의 메시지는 오직 한 번만 처리된다고 했습니다.
하지만 pub-sub 구조의 경우 하나의 메시지가 여러 소비자에게 전달되어 처리될 수 있습니다.
소비자가 특정 주제(topic)를 구독하면 이 주제로 전달되는 메시지를 받을 수 있습니다.
쇼핑몰에서 물건을 살 때, 다음과 같은 동작이 필요하다고 합시다.
- 재고 변화
- 구매 알림
- 배송
각 동작을 처리하는 소비자들은 같은 구매 topic을 구독하여 같은 그룹에 속하게 되고 구매 topic에 구매 메시지를 보내면 이 메시지가 같은 그룹 내부 모든 소비자들에게 전달됩니다.
그리고 위 3가지 동작이 각 소비자들로부터 병렬로 처리됩니다.
pub-sub의 경우 소비자를 추가하는 것도 쉽습니다.
위 3가지 동작 이외에 추가적인 동작이 필요하다면 해당 동작을 하는 소비자를 만들어서 같은 구매 topic을 구독하면 됩니다.
queues의 경우 여러 소비자들의 역할은 동일하기 때문에 각 메시지들은 오직 한 번만 처리됩니다.
그러나 pub-sub의 경우 여러 소비자들의 역할이 다르기 때문에 각 메시지들은 모든 소비자가 한 번씩 처리합니다.
pub-sub 방식은 하나의 메시지를 처리하기 위해 여러 개의 독립적인 동작이 필요할 때 유리합니다.
예를 들어 다음과 같은 상황들이 있습니다.
- 알림을 인앱 알림, 이메일, 문자로 보내야 할 때
- 이벤트가 발생했을 때, elastic search에 로깅하고 s3에 아카이빙 해야 할 때
- sns에 사진을 업로드 했을 때, 친구들에게 알림을 보내주고 타임라인을 갱신하고 로깅해야 할 때
Streams

Event Stream은 실시간으로 처리 수집되고 처리되는 지속적인 데이터의 흐름입니다.
로그와 같이 시스템에서 발생한 이벤트를 시간 순서대로 계속 저장하고 각 이벤트들은 소비된 후 제거되지 않습니다.
특정 기간 동안 발생한 모든 이벤트를 시간 순서대로 보존하고 있기 때문에 언제든지 과거 시간대의 이벤트들을 확인할 수 있습니다.
- 과거 데이터들을 가지고 다시 작업을 수행할 수 있습니다.
- 특정 시간대에 무엇이 발생했는지 추적할 수 있습니다.
- 데이터 감사에 적합합니다.
Queues vs Pub-Sub vs Streams
| 메시지 큐 | Pub-Sub | 이벤트 스트림 | |
| 전달 모델 | 1:1 통신, 메시지 확인 시 삭제. | 1:N 통신, 각 구독자가 메시지 복사본 처리. |
1:N 통신, 공유/내구성 있는 로그에서 읽기.
|
| 순서 보장 | 큐별 FIFO 목표 (재시도 시 깨질 수 있음), 전역적 일관성 아님. | 구독자 간 전역 순서 보장 안 함 (일부 예외). |
파티션 내 강력한 순서 유지.
|
| 재생 가능성 | 메시지 확인 시 폐기, 재생 불가. | 브로커에 따라 다름 (제한적 재생 가능). |
최고 수준의 재생 가능 (오프셋/타임스탬프 기반).
|
| 대기 시간 및 처리량 |
낮은 대기 시간, 병렬 소비자 수에 따라 처리량 확장. | 낮은 대기 시간, 중간 처리량 (팬아웃/느린 구독자 문제 가능). |
높은 처리량 (수백만/초), 대기 시간은 버퍼링 등에 따라 가변.
|
이제 이러한 메시지 패턴을 구현할 수 있는 대표적인 도구인 rabbitMQ와 kafka에 대해 알아봅시다.
RabbitMQ
AMQP는 메시지 지향 미들웨어(Message Oriented Middleware)에서 메시지 브로커 간 통신을 표준화하기 위해 설계된 프로토콜입니다.
서로 다른 서비스 간 소통할 때, 다른 방식을 사용하게 되면 불편하기 때문에 이러한 통신을 표준화기 위한 프로토콜이 AMQP입니다.
RabbitMQ는 AMQP 프로토콜을 구현한 대표적인 메시지 브로커입니다.

RabbitMQ의 exchange와 그 종류는 아래와 같습니다.
- exchange : 생산자가 메시지를 게시한 뒤, 큐나 스트림으로 라우팅하는 역할
- direct : 바인딩의 라우팅 키와 정확히 일치하는 라우팅 키를 사용하여 하나 이상의 바인딩된 큐, 스트림 또는 Exchange로 라우팅한다.
- topic : 메시지의 라우팅 키와 바인딩 시 사용된 라우팅(바인딩) 키 패턴 간의 패턴 매칭을 사용하여 라우팅한다.
- fanout : 자신에게 발행된 모든 메시지를 바인딩된 모든 큐, 스트림 또는 Exchange에 복사하여 라우팅합니다.
Apache Kafka

Apache Kafka는 실시간 데이터 파이프라인 및 스트리밍 애플리케이션 구축을 위한 분산 스트리밍 플랫폼입니다.
- 카프카 클러스터 (Kafka Cluster): 여러 카프카 브로커로 구성된 분산 시스템. 실시간 스트리밍 데이터 저장 및 처리 담당.
- 브로커 (Brokers): 카프카 클러스터 구성 서버. 데이터 수신, 저장, 제공 담당. 생산자/소비자 읽기/쓰기 작업 처리. 데이터 복제 관리.
- 토픽 및 파티션 (Topics and Partitions): 카프카 데이터는 토픽으로 구성. 토픽은 생산자 데이터 발행, 소비자 데이터 읽는 논리적 채널. 각 토픽은 파티션으로 나뉨. 파티션은 카프카 병렬 처리 기본 단위. 파티션 통해 데이터 여러 브로커에 분산시켜 수평적 확장 가능.
- 생산자 (Producers): 카프카 토픽에 데이터 발행.
- 소비자 (Consumers): 카프카 토픽 구독하고 데이터 처리.
- 오프셋 (Offsets): 파티션 내 각 메시지에 할당되는 고유 식별자. 오프셋 사용하여 토픽에서 메시지 소비 진행 상황 추적.
Apache Kafka vs RabbitMQ
| Apache Kafka | RabbitMQ | |
| 기본 설계 | 스트림 기록의 데이터 처리 가능한 내구성 우수 메시지 브로커 시스템. |
간단한 아키텍처로 복잡한 메시지 라우팅 제공.
|
| 성능 | 초당 수백만 개의 메시지 전송 가능. 순차 디스크 I/O 사용하여 높은 처리량 제공. |
초당 수백만 개 가능하나 여러 브로커 필요. 평균 초당 수천 개. 대기열 혼잡 시 속도 저하.
|
출처
https://eda-visuals.boyney.io/visuals/queues-vs-streams-vs-pubsub
https://blog.bytebytego.com/p/messaging-patterns-explained-pub
https://dev-gallery.tistory.com/33
https://www.cloudamqp.com/blog/amqp-vs-mqtt.html
https://www.geeksforgeeks.org/kafka-architecture/
https://aws.amazon.com/ko/compare/the-difference-between-rabbitmq-and-kafka/