Message Middleware
- 비동기 방식을 이용하여, 프로세스간 데이터를 주고 받을 수 있는 시스템
- 메시지 미들웨어는 전달하는 과정에서 데이터를 보관하거나, 라우팅 및 변환을 할 수있는 장점을 가짐
- 메시지의 백업 기능을 유지함으로 써 지속성을 제공하고, 송수신 측은 동시에 네트워크 연결을 유지할 필요가 없음
- 메시지 미들웨어는 라우팅을 수행하기 때문에, 하나의 메시지를 여러 수신자에게 전달이 가능
- 송수신측 요구에 따른 데이터를 변환할 수 있음
- 변환 예시
- Producer(송신측)
- 역할: 어플리케이션이나 서비스에서 데이터를 생성하여 메시지 큐 시스템으로 전송한다.
- 요구사항: 자신의 내부 데이터 형식을 그대로 사용하여 메시지를 전송한다.
- TransformationModule(변환 모듈)
- 역할: Producer가 전송한 메시지를 수신하여, Consumer(수신측)가 요구하는 형태로 데이터를 변환한다.
- 변환 방식
- 데이터 매핑: XML태그와 JSON필드를 대응시켜 데이터 구조를 재구성한다.
- 스키마 변환: 기존 데이터 스키마를 새로운 스키마에 맞게 변경한다.
- 필드 변환: 필요없는 데이터 제거 혹은 추가 데이터를 삽입하는 등 세밀한 변한 작업을 수행한다.
- MessageQueue(메시지 큐)
- 역할: 변환된 메시지를 임시로 저장하고, Consumer에게 전달하는 역할을 수행한다.
- 특징: 데이터의 안정적 저장, 순서 보장, 재전송 기능 등을 제공하여 시스템의 신뢰성을 높인다.
- Consumer(수신측)
- 역할: 메시지 큐에서 전달받은 메시지를 자신의 시스템에서 처리
- 요구사항: JSON과 같은 자신이 이해하고 처리할 수 있는 데이터 형식을 요구하며, 이를 통해 비즈니스 로직에 적용한다.

Message Queue?
- Queue라는 것은 선입선출방식의 자료구조
- 메시지 큐는 이러한 Queue 자료구조를 이용하여, 메시지를 전달하는시스템이며, 메시지 미들웨어를 구현한 시스템
- 메시지큐를 통해 메시지를 전달하려면 전달하는 부분을 Producer, 전달받는 부분을 Consumer라고 함
- MSA 아키텍쳐에서 핵심적인 역할을 함
핵심 역할
- 서비스 간 느슨한 역할
- 각 서비스가 서로 직접 호출하지 않고, 메시지를 주고 받음으로써 서로 독립적으로 동작할 수 있다. 이로 인해 하나의 서비스에 변경이나 장애가 발생해도 전체 시스템에 미치는 영향을 최소화할 수 있다
- 즉, 각각의 서비스들은 서비스간 호출이 아닌 독립된 메시지큐시스템을 이용하여 메시지를 주고 받음으로써, 장애를 최소화로 줄일 수 있다.
- 비동기 통신
- 요청과 응답이 동시에 일어나지 않아도 되므로, 각 서비스는 자신에게 맞는 속도로 작업을 처리할 수 있다. 이는 시스템의 응답성과 효율성을 높인다.
- 각 서비스들은 메시지 처리 요청을 했을 때 응답을 기다릴 필요 없이 이후의 작업을 진행하면된다.
- 다른 서비스에서 메시지 처리가 완료되어 응답이 왔을 경우 이벤트 큐에 해당 메시지를 넣어두고, 현재 진행 중인 작업이 완료되거나, 잠시 중단(예, await yield)이 됐을 경우 이벤트 큐를 탐색하여 처리할 메시지를 꺼내어 작업을 처리한다.
- 신뢰성과 내구성
- 메시지 큐는 메시지를 안전하게 저장하고, 일시적인 장애 상황에서도 메시지가 손실되지 않도록 보장한다. 실패한 작업은 재시도할 수 있어 전체 시스템의 안정성을 높인다.
- 부하 분산
- 대량의 요청을 일시적으로 저장하고, 각 서비스가 처리 가능한 만큼 메시지를 분산시켜 작업을 수행할 수 있도록 도와준다. 이를 통해 특정 서비스가 과부하에 걸리지 않고 전체 시스템의 부하를 균등하게 분산시킬 수 있다.
- 확장성
- 서비스들이 독립적으로 운영되고, 메시지 큐시스템을 통해 통신하기 때문에, 각 서비스들은 별도로 확장될 수 있다. 이는 시스템 전체의 확장성을 크게 향상 시킨다.
- 각 서비스 별로 유지보수나, 업데이트 혹은 신규 서비스가 생성이 되더라도 메시지 큐 시스템을 통해 통신하므로써, 확장성을 향상 시킬 수 있다.
메시지 큐 분산 방식
- 경쟁 소비자 패턴(Competing Consumers)
- 하나의 큐에 여러 서비스(Consumer)가 동시에 접근하여 메시지를 가져가 처리하는 방식으로, 각 서비스가 자신이 처리할 수 있는 만큼 메시지를 가져가므로 전체 부하가 자연스레 분산된다.
- 서비스 별 메시지 처리 수치는 프리페치 설정 값을 통해 지정하여 사용한다.
- 라운드 로빈 분배
- 큐에 들어온 메시지를 순차적으로 서비스로 배분하는 방식으로, 모든 서비스가 균등하게 작업을 할당받을 수 있게 도와준다.
- 프리페치(Prefetch) 설정
- 서비스가 한 번에 가져올 메시지의 개수를 제한하는 설정을 말한다. 이를 통해 각 서비스는 처리 능력에 맞게 메시지를 받아 과부하가 발생하지 않도록 조절할 수 있다.
- 메시지 라우팅 및 토픽 기반 분배
- 메시지에 라우팅 키나 토픽을 부여하면 특정 조건에 맞는 메시지를 특정 큐나 서비스 그룹에 전달할 수 있으며, 전문화된 서비스들이 특저 유형의 작업만 처리하도록 함으로써 부하를 효과적으로 분산시킨다.
- 클러스터링 및 샤딩
- 메시지 큐 자체를 여러 서버에 분산시켜 운영할 수 있으며, 여러 노드에 메시지를 분산시키면 한 서버에 과도한 부하가 집중되는 것을 방지하고, 전체 시스템의 확장성과 안정성을 높일 수 있다.
메시지 브로커 VS 이벤트 브로커
메시지 브로커
- 메시지 브로커는 Producer와 Consumer 사이에 데이터를 중개하는 컴포넌트로, Producer가 보내는 메시지를 Queue에 저장하고, 이 저장된 메시지를 Consumer에게 안정적으로 전달함으로써, 데이터 전송의 신뢰성과 순서를 보장한다.
- 컨슈머 별 Queue에 접근하기 때문에 프로듀서가 전달한 메시지 순으로 데이터를 찾아 전달하기 때문에, 순서를 보장한다.
- 메시지 브로커는 아래의 메커니즘으로 인해 신뢰성을 보장한다.
신뢰성 보장 메커니즘
- 영구 저장(Presistence)
- 프로듀서가 보낸 메시지는 디스크와 같은 영구 저장소에 기록되어, 시스템 장애나 재시작 상황에서도 메시지를 복원할 수 있다.
- 확인(acknowledgment)
- 컨슈머가 메시지를 성공적으로 처리했음을 브로커에 알리는 확인 메시지 ack를 사용한다. 확인되지 않은 메시지는 재전송되어 데이터 손실을 방지한다.
- 재전송 및 중복 제거
- 메시지 전송 중 실패가 발생하면, 브로커는 자동으로 재전송 기능을 사용하여 메시지를 재전송한다. 동시에 중복 수신을 방지하는 로직이 존재해, 동일한 메시지가 여러번 처리되지 않도록 관리한다.
- 순서 보장
- FIFO(First-In-First-Out) 큐를 사용하거나, 순서에 민감한 메시지 처리를 위한 추가 메커니즘을 도입하여 메시지가 올바른 순서로 처리되도록 한다.
- 트랙잭션 지원
- 일부 메시지 브로커는 트랙잭션을 지원하여, 메시지 전송과 처리 과정이 모두 원자적으로 이루어지도록 보장함으로써, 중간에 오류가 발생하더라도 시스템 전체의 일관성을 유지한다.
중개 과정
- 메시지 수집
- 프로듀서가 생성한 메시지를 브로커가 수신하고, 이를 큐에 순차적으로 저장한다.
- 저장 및 관리
- Queue는 FIFO(FirstIn FirstOut)방식 등으로 메시지를 관리하며, 메시지의 순서와 중복 제거, 재전송 같은 기능을 지원하여 장애 상황에서도 데이터가 안전하게 전달되도록 한다.
- 메시지 전달
- 컨슈머는 필요 시 큐에서 메시지를 꺼내 처리함으로써, 메시지의 안정적이고 신뢰성있는 전달을 보장받는다.
구조
graph LR
%% Producers
subgraph Producers [프로듀서]
P1[Producer 1]
P2[Producer 2]
end
%% Message Broker
subgraph Broker [메시지 브로커]
Q1[Queue / Exchange]
TM[Transformation / Routing Module]
M[메시지 저장 및 관리]
end
%% Consumers
subgraph Consumers [컨슈머]
C1[Consumer 1]
C2[Consumer 2]
end
%% Message flow arrows
P1 -->|메시지 전송| TM
P2 -->|메시지 전송| TM
TM --> Q1
Q1 --> M
M -->|메시지 전달| C1
M -->|메시지 전달| C2
- Producer
- 역할: 데이터를 생성하여 메시지 브로커로 메시지를 전송한다.
- 특징: 여러 어플리케이션이나 서비스가 독립적으로 동작하며, 다양한 형식의 메시지를 전송할 수 있다.
- 예) 주문 시스템, 센서 데이터 수집기, 사용자 이벤트 기록기
- Message Broker
- 역할
- Transformation / Routing Module
- 역할: Producer로부터 받은 메시지를 필요에 따라 데이터 형식 변환, 필터링 또는 분류 작업을 수행한다.
- 설정: 송수신측의 요구사항에 따라, 미리 정의된 규칙이나 동적 설정을 통해 메시지 변환 및 라우팅 규칙을 적용한다.
- Queue / Change
- 역할: 메시지를 저장하고 해당 메시지를 어떤 Consumer에게 전달할지 결정한다.
- 특징
- Queue: 기본적으로 메시지를 FIFO방식으로 저장하여 전달한다.
- Exchange: 라우팅 키, 바인딩 규칙 등을 기반으로 메시지를 여러 큐나 Consumer에게 분배할 수 있다.
- Message Storage & Management
- 역할: 메시지의 안정적인 저장, 재전송, 우선순위 관리 등 신뢰성 있는 메시지 전송을 지원한다.
- 특징: 고가용성 클러스터링, 장애복구, 모니터링 및 관리 인터페이스를 제공한다.
- Consumer
- 역할: 메시지 브로커로부터 전달받은 메시지를 수신하여 처리한다.
- 특징
- 여러 Consumer가 동시에 작업 부하를 분산 처리할 수 있다.
- 메시지의 순서를 유지하거나, 병렬 처리 등 다양한 방식으로 데이터를 처리할 수 있다.
이벤트 브로커
- 이벤트 브로커는 이벤트 발행자(Publish)와 구독자(subscriber) 사이에서 발생하는 이벤트를 중개하는 컴포넌트로, 시스템 내에서 발생하는 상태 변화나 특정 동작을 실시간으로 수집하고, 이를 Pub/Sub모델에 따라 관심 있는 여러 구독자에게 즉시 전달함으로써 시스템 간의 느슨한 결합과 빠른 반응을 이끌어낸다.
중개 과정
- 이벤트 수집: 발행자가 이벤트를 생성하면, 이벤트 브로커가 이를 받아들입니다.
- 주제별 분류 및 관리: 수집된 이벤트는 Topic이나 카테고리 별로 분류되어 관리되며, 이벤트 내용에 따라 필터링 또는 변환이 이루어질 수 있습니다.
- 실시간 전파: 관심있는 구독자들이 해당 Topic을 구독하고 있다면, 이벤트 브로커는 이들을 대상으로 이벤트를 거의 실시간에 가깝게 전파하여, 즉각적인 대응이나 처리가 가능하도록 한다.
기본 구성 요소
- 이벤트 프로듀서(Event Producer)
- 시스템, 센서, 어플리케이션 등에서 발생하는 상태 변경, 사용자 활동 등의 이벤트를 생성한다.
- 이벤트 라우터/변환 모듈(Event Router/Transformer)
- 프로듀서로부터 수신한 이벤트를 필요한 경우 데이터 형식이나 구조를 변환하고, 사전 정의된 규칙에 따라 적절한 경로로 라우팅한다.
- 이벤트 프로세서(Event Processor)
- 이벤트를 필터링, 집계, 분석하거나 비즈니스 로직을 적용하는 역할을 한다.
- 이벤트 저장소(Event Store)
- 이벤트를 일시적으로 저장하거나, 이벤트 소싱 패턴을 지원하여 후속 처리를 위해 이벤트 로그를 보관한다.
- 이벤트 컨슈머(Event Consumer)
- 이벤트를 전달받아 실제 비즈니스 처리를 실행하거나, 후속작업(알림, 데이터 업데이트, 보고 등)을 실행한다.
구조
graph LR
%% Event Producers
subgraph Producers [이벤트 프로듀서]
EP1[Producer 1]
EP2[Producer 2]
end
%% Event Broker Components
subgraph EventBroker [이벤트 브로커]
ER[이벤트 라우터/변환 모듈]
EP[이벤트 프로세서]
ES[이벤트 저장소]
end
%% Event Consumers
subgraph Consumers [이벤트 컨슈머]
EC1[Consumer 1]
EC2[Consumer 2]
end
%% 이벤트 흐름
EP1 -->|이벤트 전송| ER
EP2 -->|이벤트 전송| ER
ER -->|필터링/변환| EP
EP -->|처리된 이벤트 기록| ES
ES -->|이벤트 전달| EC1
ES -->|이벤트 전달| EC2
- 이벤트 프로듀서
- 역할: 어플리케이션, IoT센서, 사용자 인터랙션 등에서 발생하는 이벤트(상태변화, 트리거 등)를 생성한다.
- 특징: 이벤트를 실시간으로 발생시키며, 이벤트 브로커에 전송하여 시스템 간 통신의 시작점을 제공한다.
- 이벤트 라우터/변환 모듈(Event Router/Transformer)
- 역할: 수신된 이벤트를 분석하여, 필요에 따라 데이터 형식을 변환하거나, 이벤트 내용을 필터링한 후 적절한 처리 경로로 전달한다.
- 설정 방식
- 사전 정의된 룰(예: JSON 스키마 매핑, 필드 변환 규칙 등)이나 동작 설정을 사용하여 이벤트를 라우팅하며, 시스템 통합팀이나 데브옵스팀이 관리한다.
- 이벤트 프로세서
- 역할: 이벤트를 실시간으로 처리하여 집계, 분석, 알림 또는 다른 시스템으로의 전달 등 다양한 비즈니스 로직을 수행한다.
- 특징: 복잡한 이벤트 처리나 스트림 처리 기능을 제공하며, 필터링이나 조건부 처리를 통해 불필요한 이벤트는 제거하고 중요한 이벤트만을 선별한다.
- 이벤트 저장소
- 역할: 이벤트를 임시 또는 영구적으로 저장하여, 후속 분석, 재처리 또는 이벤트 소싱 패턴에 활용할 수 있도록 한다.
- 특징: 이벤트 로그 형태로 저장하여, 과거의 이벤트 이력을 기반으로 시스템의 상태를 재구성할 수 있도록 지원한다.
- 이벤트 컨슈머
- 역할: 저장소나 실시간 스트림으로 이벤트를 수신하여, 비즈니스 처리, 데이터 업데이트, 사용자 알림 등의 작업을 수행한다.
- 특징: 여러 컨슈머가 동시에 이벤트를 처리함으로써, 시스템의 확장성과 고가용성을 지원한다.
아카이브
이벤트 브로커
- 데이터를 운반하는 방식에 따라 메시지 브로커와 이벤트 브로커로 나눠짐
- 브로커라는 것은 메시지 큐의 메시지 혹은 이벤트를 넣어주고 중개하는 역할을하는 서버
- 메시지 브로커
- Producer가 생산한 메시지를 큐에 저장하고, 저장된 메시지를 Consumer가 가져갈 수 있도록함
- Consumer가 메시지 큐에서 데이터를 가져갈 경우 짧은 시간내에 메시지큐에서 데이터를 삭제함
- 예) ActiveMQ, SQS, Redis
- 이벤트 브로커
- 기본적으로 메시지 브로커의 역할을 할 수 있으나, 메시지 브로커는 그러지 못함
- 관리하는 데이터를 이벤트라고 표현하고, Consumer가 큐에서 데이터를 가져게가 되면 짧은 시간 내에 매시지를 삭제하는 메시지 브로커와 달리, 이벤트 브로커는 Consumer가 데이터를 필요할 경우 다시 재활용할 수 있음 -> 삭제하지 않음
- 예) Kafka
장점
비동기
- 메시지큐가 없을 경우 메시지를 발행하는 Producer와 메시지를 받는 Consumer를 직접 개발하여 직접적으로 메시지를 보내야함
- End-To-End통신을 통해 메시지 전달이 이뤄질텐데, 해당 과정들이 완료되기 전까지는 다른 메시지 전달을 진행하지 못함
- 즉, 동기 처리형태로 진행이 되어야 될텐데, 전송속도가 빠르고 결과를 신속하게 알 수는 있지만, 대용량 트래픽이 발생하는 서버일 경우 비효율적인 방법이며, 메시지 큐를 통해 비동기적으로 메시지 발행 및 받는 작업에 대해 비동기적으로 처리가 가능
낮은 결합도
- 메시지 큐를 통해 하나의 서비스를 구성하는 어플리케이션끼리의 결합도를 낮출 수 있음
- 결합도가 낮을 경우 확장성, 유연성, 효율적인 유지보수, 장애전파방지 등에 대한 처리하기가 수월함
탄력성
- 탄력성이란 시스템이 얘기치 않은 상황 또는 장애에 대응하고 유연하게 대처할 수있는 능력
- 메시지 큐의 탄력성 특성 덕분에 Producer 프로세스는 Consumer 프로세스가 다운되어 있어도, 메시지 발행은 정상적으로 가능하고, 반대로 Producer 프로세스가 다운되었어도 메시지 수신은 정상적으로 가능
과잉성
- 과잉성은 정상적인 메시지 송/수신이 실패하는 경우 재실행이 가능한 특성
- 메시지큐가 없는 상태에서 A,B 프로세스간 통신을 하는 상황에서, 프로세스간 장애가 발생했을 경우 정상적으로 메시지를 송/수신할 수 없으며, 어플리케이션 수준에서 시스템응답성저하, 데이터 불일치, 메시지 유실 문제가 있을 수 있음
- 메시지큐를 사용할 경우 이를 완화할 수 있으며, 작업을 메시지로 큐에 넣어두면 일정 장애기간동안 송신된 메시지는 큐에 남아있어 추후 장애 복구 및 재시도가 가능
신뢰성
- 신뢰성이란 송신된 데이터가 얼마나 안전하고 확실한 전달인지를 의미하는 특성
- 프로세스간 장애가 발생하더라도 송신 메시지를 안전하고 확실하게 수신할 수 있음
확장성
- 메시지큐를 이용한 통신에서 부하가 증가하거나, 클라이언트의 동시다발적인 요청이 증가할 경우, 메시지 큐에 Producer와 Consumer를 추가함으로써 비교적 쉽고 간단하게 확장을 할 수 있음