[개념원리]Message Queue

봄도둑·2022년 7월 28일
1

개념원리

목록 보기
1/3

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 패턴들이 트랜잭션 처리를 위해 메시지큐를 사용하기 시작
  • 예시)이메일 전송 시스템
    • 비밀번호를 잊어버렸을 때 재발급 받는 시스템


      (사진 출처 : https://tecoble.techcourse.co.kr/post/2021-09-19-message-queue/)

    • 비밀번호 재설정을 위해 이메일을 발급하는 서비스, 회원가입을 위해 이메일을 발급 받는 서비스 → 메시지(이메일)을 큐에 넣음

    • 이메일 전송 전용 서비스는 메시지(이메일)이 어느 서비스로부터 producing 되었는지 상관없이 consumer가 메시지큐에 쌓인 메시지(이메일)을 처리함 → 이메일이 보내져야할 곳으로 어쨌든 이메일이 전송됨.

1-2. AMQP

Message Queue의 오픈소스에 기반한 표준 프로토콜 → 이 자체로 프로토콜을 의미하기 때문에 AMQP를 따른 대표적인 것은 RabbitMQ

  • AMQP의 목적

    • 서로 다른 시스템 간에 최대한 효율적인 방법으로 메시지를 교환하기 위한 MQ 프로토콜
  • AMQP는 벤더에 종속되는 것을 방지하기 위해 다음과 같은 조건을 충족해야함

    • 모든 broker들이 동일한 방식으로 동작
    • 모든 client들이 동일한 방식으로 동작
    • 네트워크로 전송되는 명령들의 표준화
    • 프로그래밍 언어에 중립적임
  • AMQP Routing Model


    (사진 출처 : http://mutlix.blogspot.com/search/label/AMQP)

    • AMQP의 라우팅 모델은 exchange, binding, queue 3가지 핵심 컴포넌트로 구성 → AMQP는 이러한 구성요소들이 어떻게 통신할지를 정의한 프로토콜
      • Exchange : publisher로부터 수신한 메시지를 적절한 큐 또는 다른 exchange에 분배. 수신한 메시지를 binding에 따라 적합한 큐나 exchange로 라우팅. 일종의 우체국 역할
        • exchange type은 메시지를 어떤 방법으로 라우팅 시킬 것인지, binding은 이러한 방법을 통해 어떤 메시지를 어떤 큐에 보낼지를 결정하는 라우팅 테이블
      • queue : 메시지를 저장하고 consumer에게 전달하는 역할
      • binding : exchange와 queue의 관계를 정의한 일종의 라우팅 테이블. 같은 큐가 여러 개의 exchange에 binding 될 수 있고, 하나의 exchange에 여러 개의 queue가 binding 될 수 있음
      • routing key : publisher에서 송신한 메시지 헤더에 포함되는 일종의 가상 주소. exchange는 routing key를 이용해 어떤 큐로 메시지를 라우팅 할지 결정. AMQP의 표준 exchange type은 이 라우팅 키를 이용
    • Exchange type
      • Direct exchange : binding된 queue 중에서 메시지의 routing key와 매핑되어 있는 queue로 메시지 전달(1:1) → unicast 방식에 적합, 라운드 로빈 방식으로 여러 consumer간 task 분리에 사용

      • Fanout exchange : 메시지의 routing key를 무시하고 exchange에 바인딩된 모든 queue에 메시지 전달(1:N) → 메시지를 브로드캐스트할 때 적합. 모든 서비스를 키거나 끌 때 사용

      • Topic exchange : 메시지의 routing key가 패턴에 맞는 queue에게 모두 메시지 전달(아래 사진의 경우 1번, 3번에게 전달)


        (사진 출처 : http://egloos.zum.com/killins/v/3025514)

      • Headers exchange : routing key 대신 메시지 헤더의 속성들로 해당 속성들이 매칭되는 큐에게 메시지 전달(아래의 이미지에서는 1, 3번 전달 | any는 or와 같은 의미)

        (사진 출처 : http://egloos.zum.com/killins/v/3025514)

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

profile
Java Spring 백엔드 개발자입니다. java 외에도 다양하고 흥미로운 언어와 프레임워크를 학습하는 것을 좋아합니다.

0개의 댓글