Message Queue에 대한 개념 및 여러 오픈소스에 대해 설명합니다.
1. Message Queue 개념
- 메시지 지향 미들웨어(Message Oriented Middleware : MOM)
- 비동기 메시지를 사용하는 다른 응용 프로그램 사이의 데이터 송, 수신을 의미
- 이러한 MOM을 구현한 시스템이 Message Queue
- 메시지큐는 프로세스(또는 프로그램 인스턴스)가 데이터를 서로 교환할 때 사용하는 방법
- 서로 다른 프로세스(또는 프로그램) 사잉에 메시지를 교환할 때 AMQP(Advanced Message Queuing Protocol)을 사용 → 시스템 간 메시지를 교환하기 위해 공개 표준으로 정의한 프로토콜
- AMQP를 사용하면 다른 벤더 사이에 메시지를 전송하는 것이 가능해짐 → octet stream을 이용해서 다른 네이트워크 사이에 데이터를 전송할 수 있는 포맷으로 사용
- 메시지큐는 메시지를 임시로 저장하는 간단한 버퍼
- 메시지 전송 시 producer 컴포넌트가 메시지를 메시지큐에 추가 → 해당 메시지는 consumer 컴포넌트가 메시지를 검색하고 이를 사용해 특정 작업을 수행할 때 까지 메시지큐에 저장
- 각 메시지는 하나의 소비자에 의해 한 번만 처리 → 1:1 통신 방식
1-1. Message Queue의 사용처
간단한 서버 구조에서는 굳이 사용자의 요청과 응답에 시간이 소요되는 메시지큐를 사용할 이유는 없음.
- 메시지큐는 consumer가 실제로 메시지를 어느 시점에서 가져가서 처리해야할지 보장되지 않음 → 언젠가 메시지큐에 넣어둔 메시지가 소비되어 처리될 것 ⇒ 비동기적 특징
- 대용량 데이터를 처리하기 위한 배치 작업, 채팅 서비스, 비동기 데이터를 처리할 때 사용
- 사용자가 많아지거나 데이터가 많아지면 응답 지연으로 서비스가 정상적으로 작동하지 못하는 상황이 올 수 있음 → 기존에 분산되어 있던 데이터 처리를 한 곡에 집중하면서 메시지 브로커를 통해 필요한 프로그램에 작업을 분산시키는 방법
- 실패하면 치명적인 핵심 작업보다 어플리케이션의 부가적인 기능에 사용하는 것이 적합
- 그러나 MSA의 구현이 중요시되면서 많은 MSA 패턴들이 트랜잭션 처리를 위해 메시지큐를 사용하기 시작
- 예시)이메일 전송 시스템
1-2. AMQP
Message Queue의 오픈소스에 기반한 표준 프로토콜 → 이 자체로 프로토콜을 의미하기 때문에 AMQP를 따른 대표적인 것은 RabbitMQ
1-2. Message Queue의 장점
- 비동기
- 생산된 메시지의 저장, 전송에 대해 동기화 처리를 하지 않음 → 메시지큐에 넣어두기 때문에 나중에 처리할 수 있음
- 동기적 방식은 많은 메시지가 전송될 경우 병목이 발생할 가능성↑
- 낮은 결합도
- producer와 consumer가 독립적으로 행동 → 서비스 결합도가 낮아짐
- 확장성
- 다수의 프로세스들이 큐에 메시지를 보낼 수 있음
- 탄력성
- consumer 서비스가 다운되더라도 애플리케이션이 중단되지 않고 메시지는 메시지큐에 계속 남아있음 ⇒ 서비스 일부의 실패가 시스템 전체에 영향을 주지 않음
- 보장성
- 큐에 보관되어 있는 모든 메시지들이 결국에는 consumer에 의해 처리됨을 보장
2. Message Queue 오픈소스
2-1. RabbitMQ
오픈소스 AMQP 브로커
- 신뢰성, 안정성과 성능을 충족할 수 있는 기능들 제공
- 유연한 라우팅 : Message Queue가 도착하기 전에 라우팅, 플러그인을 통해 더 복잡한 라우팅도 가능
- 클러스터링 : 로컬 네트워크에 있는 여러 RabbitMQ 서버를 논리적으로 클러스터링 할 수 있음
- 실시간 모니터링 및 관리가 용이
- 모든 언어와 운영체제를 지원 → 단, window 이용시 Erlang, OpenSSL 설치 필요 ⇒ 요거 docker를 쓰면 간단히 해결!
2-2. ActiveMQ
JMS(풀 자바 메시지 서비스) 클라이언트와 함께 자바로 만든 오픈 소스 메시지 브로커
- JMS
- MOM를 자바에서 지원하는 표준 API(AMQP는 프로토콜)
- JMS는 다른 자바 애플리케이션들끼리 통신은 가능하지만 다른 MOM과는 통신 불가(AMQP etc...)
- 반면 AMQP는 프로토콜만 맞다면 다른 AMQP를 사용한 애플리케이션끼리 통신 가능
- JMS 라이브러리는 AMQP 지원 X
- 다양한 언어 환경의 클라이언트와 프로토콜 지원
- Spring 지원으로 ActiveMQ는 Spring 애플리케이션에 쉽게 임베딩 + XML 설정이 쉬움
- REST API를 통해 웹 기반 메시징 지원
- RabbitMQ와는 다르게 모니터링 도구가 부실함
- Dead letter queue 지원
2-3. ZeroMQ
임베디드 네트워킹 라이브러리이지만 동시에 프레임워크 기능도 수행
- AMQP보다 매우 빠름 → 복잡한 프로토콜이 없고, Y-suite IPC 전송 같은 효율적인 전송 활용
- 비동기 send 호출만 하면 메시지를 스레드의 큐에 넣고 필요한 모든 일을 해줌 → 이벤트 중심의 프레임워크에 적합
2-4. Kafka
대용량 실시간 로그 처리 특화 → 특화된 시스템이기 때문에 범용 메시징 시스템에서 제공하는 기능들은 사용하기 힘듦
- AMQP나 JMS를 사용하지 않고 단순 메시지 헤더를 지닌 TCP 통신
- 개별 전송이 아닌 다수 전송 가능(Batch 처리 가능) → TCP/IP 라운드트립 횟수를 줄임
- 파일 시스템 저장(기존 메시징 시스템은 메모리에 저장) ⇒ 별도의 설정을 해주지 않아도 데이터의 영속성이 보장됨
- 파일 시스템에 메시지가 저장되기 때문에 메시지를 많이 쌓아두어도 성능이 크게 감소하지 않음 + 메시지를 쌓아둘 수 있기 때문에 실시간 처리 뿐만 아니라 주기적인 batch 작업에 사용할 데이터 적재도 가능
- 처리된 메시지를 파일 시스템에 두었다가 설정 수명이 지나면 삭제 처리 → 처리된 메시지를 일정 기간동안 삭제하지 않기 때문에 메세지 처리 도중 문제가 발생하였거나 로직이 변경되었을 경우 consumer가 메시지를 처음부터 다시 처리하도록 할 수 있음
- 메시지를 pull 방식으로 가져옴 → 메시지를 쌓아두었다가 주기적으로 처리하는 batch consumer의 구현이 가능
- 분산 시스템을 기본으로 설계 → 기존 메시징 시스템에 비해 분산 및 복제 구성이 쉬움
- 기존 메시징 시스템은 brocker가 consumer에게 메시지를 push → kafka는 consumer가 broker로부터 직접 메시지를 가지고 가는 pull 방식 → consumer는 처리 능력 만큼의 메시지만 broker로부터 가져올 수 있음 → 성능의 최적화
- 메시지를 pull 방식으로 가져옴 → 메시지를 쌓아두었다가 주기적으로 처리하는 batch consumer의 구현이 가능
- broker의 consumer와 메시지 관리에 대한 부담 및 리소스 경감
- queue의 기능은 RabbitMQ 등 AMQP 보다 부족함 → 이들과 차별화되는 강점은 대용량 메시지를 지원할 수 있다는 것! ⇒ 용량문제에 있어 확실한 강점이 있음
*REFERENCE
https://sugerent.tistory.com/644
https://tecoble.techcourse.co.kr/post/2021-09-19-message-queue/
https://heodolf.tistory.com/49
https://ram2ram2.tistory.com/3
https://cheese10yun.github.io/spring-rabbitmq/
https://12bme.tistory.com/176