프로젝트를 진행하며 채팅 시스템에 사용될 '비동기 메시지 큐'를 구현하기 위해 메시지 브로커(Message Broker)에 대해 학습했고, 이 과정에서 얻은 지식들을 정리하는 포스팅을 연재해 볼까 합니다.
이 포스팅은 연재의 첫 번째로써 메시지 브로커에 대한 이해를 바탕으로 한 꺼풀씩 풀어보고자 합니다.
메시지 브로커란?
메시지 브로커는 애플리케이션 간 서로 통신할 때 정보를 주고받을 수 있도록 도와주는 소프트웨어입니다.
우체국처럼 메시지를 보내는 쪽인 생산자(Producer)와 메시지를 받는 쪽인 소비자(Comsumer) 사이에서 메시지를 전달하는 역할을 수행합니다.
그렇기 때문에 MSA(Micro Service Architecture) 또는 분산 시스템에서 서비스 간 통신에 주로 사용되는 경우가 많고, 시스템 로그 처리, 비동기 메시지 큐 등 다양한 곳에서 활용됩니다.
왜 메시지 브로커가 필요할까요?
비동기 처리
보통 우리가 만드는 애플리케이션은 멈춰있지 않습니다.
WAS 에서 HTTP Request 메시지를 처리할 때도 별개의 스레드에서 응답을 처리합니다.
더 쉬운 예시를 들어볼까요?
편지를 받는 사람(Consumer)은 편지를 쓰는 사람(Producer)이 편지를 다 쓸 때까지(메시지를 생산할 때까지), 멍 때리며 가만히 있지 않습니다. 무언가 일을 하고 있다가 편지를 받으면 비로소 편지를 읽기 시작할 겁니다.
서비스도 마찬가지 입니다.
한 서비스(Consumer)가 다른 서비스(Producer)로부터 메시지를 받기 전까지 (비동기적으로) 자신의 일을 하다가 메시지를 받으면 그 메시지를 처리할 것입니다.
지극히 당연한 이야기처럼 들리겠지만, 이는 서비스들이 비동기로 작동할 수 있어야만 가능합니다.
중간에 다른 일을 처리하도록 말이죠.
메시지 브로커는 우체국과 같은 역할을 합니다.
한 서비스(Producer)가 메시지를 생산해서 메시지 브로커에게 전달하면 규칙에 따라 다른 서비스(Consumer)에게 메시지를 전달합니다.
이런 구조 덕분에 메시지 브로커를 이용하면 서비스들은 좀 더 쉽게 비동기로 동작할 수 있는 거죠.
시스템 간 결합도 감소
메시지 브로커를 이용하면 각 서비스들은 직접적으로 메시지를 교환하지 않습니다.
그렇기 때문에 각 서비스들을 서로 결합도가 낮아지게 됩니다. 결과적으로 각 서비스들은 독립적으로 개발과 운영이 쉬워지게 됩니다. 이런 확실한 이점 때문에 MSA 에서 활용되는 경우를 많이 볼 수 있습니다.
이 외에도 메시지 처리량이 늘면 메시지 브로커를 확장하기 용이하고, 메시지 전달이 실패해도 재전송을 통해 데이터 손실을 방지할 수 있다는 점도 있습니다.
메시지 브로커의 주요 기능
왜 메시지 브로커가 필요한지 알게 되었으니, 주요 기능을 알아봅시다.
- 메시지 전달: 우체국처럼 메시지를 전달하는 기능이 가장 주요한 기능이라 볼 수 있습니다.
- 메시지 큐: 자료구조 Queue 처럼 메시지의 순서를 보장하고, 순서대로 전달합니다.
- 토픽/채널: 메시지를 토픽 별로 분류하고, 특정 소비자한테 전달할 수 있습니다. 우체국의 우편물 분류를 생각하면 됩니다.
- 메시지 변환: 전달받은 메시지를 변환하여 공통의 형식으로 전달할 수 있습니다. 이 기능으로 인해 호환성 문제가 줄어들 수 있겠죠.
- 메시지 필터링: 메시지를 필터링하여 설정한 조건에 해당하는 소비자한테만 전달할 수 있습니다.
메시지 브로커의 종류
메시지 브로커의 종류는 어떤 것이 있을까요?
대표적인 메시지 브로커 3가지를 꼽자면 RabbitMQ, ActiveMQ, Apache Kafka 가 있습니다.
3가지 종류 모두 오픈소스를 지원하는데, 각 메시지 브로커마다 지원하는 기능이 다릅니다.
RabbitMQ
- AMQP(Advanced Message Queuing Protocol) 표준을 따르고, 지원하는 프로그래밍 언어가 다양합니다.
- Exchange 와 Queue 를 통해 라우팅을 유연하게 설정할 수 있습니다.
- Fanout / Direct / Topic 등 기본으로 제공되는 라우팅 방식과 커스텀 라우팅을 지원합니다.
- 트랜잭션, 메시지 확인 등 Admin 페이지를 기본으로 제공합니다.
- 클러스터링 기능도 제공하기 때문에 확장하기 용이하지만, Kafka 보단 확정성이 떨어집니다.
ActiveMQ
- JMS(Java Message Service) 표준을 따르고, Java 환경에서 사용하기 편리합니다.
- 다양한 메시지 형식과 트랜잭션, 클러스터링 등 다양한 기능을 제공합니다.
Kafka
- 분산 로그 시스템 기반이기 때문에 대규모 데이터 처리에 최적화되어 있습니다.
- 대규모의 메시지를 실시간으로 처리할 수 있는 높은 처리량을 제공합니다. 그렇다고 RabbitMQ 가 대규모 환경에서 사용할 수 없다는 뜻은 아닙니다.
- 분산 시스템으로 구성되어 있어 특정 노드에 장애 발생에도 시스템 전체가 중단되지 않습니다.
- 다만 설정이 복잡하고, 책에 의하면 최근엔 KRaft 에 의해 Apache Zookeeper 의존도가 줄어들었다고 하지만 아직 모든 기능이 KRaft 에 마이그레이션 되지 않았다고 합니다.
- AMQP 를 지원하지 않기 때문에 해당 프로토콜을 사용하는 시스템과 연동이 힘들 수 있습니다.
메시지 브로커들은 각각 장단점이 있습니다.
저는 여러 장단점을 고려한 끝에 분산 채팅 시스템에는 AMQP 를 지원하는 RabbitMQ 를 프로젝트에 사용했습니다.
다음 포스팅에선 AMQP(Advanced Message Queuing Protocol) 에 대해 알아보는 시간을 가져보겠습니다.
도움이 되셨길 바라며
읽어주셔서 감사합니다.
'Message Broker' 카테고리의 다른 글
[RabbitMQ] 3. 스프링 부트에서 RabbitMQ 설정 방법 (2) | 2024.08.22 |
---|---|
[RabbitMQ] 2. AMQP 란? (0) | 2024.08.16 |