본문 바로가기
IT정보

MQTT AMQP RabbitMQ

by 혀나Lee 2016. 10. 21.

MQTT (MQ Telemetry Transport)

MQTT는 경량의 Publish/Subscribe(Pub/Sub) 메시징 프로토콜이다. 네트워크가 불안정한 장소에서 작동하는 기능이나 힘이 약한 장치로 움직이는 기능을 위해 경화한 한 것이 특징이다. M2M(machine-to-machine)와 IoT(Internet of things)에서 사용하려고 만들었다. IoT를 위해서 낮은 전력, 낮은 대역폭 환경에서도 사용할 수 있도록 설계됐다. 


이름에서도 알 수 있듯이 부하를 분산시키기위한 Job Queue 기능은 없다. 이러한 용도로는 보통 AMQP 등을 사용한다.


또한 아래의 그림에서 볼 수 있듯이, MQTT는 저전력, 신뢰할 수 없는 네트워크, No TCP/IP 기반에서 운용할 수 있다는 장점이 있다. 소형기기의 제어와 센서정보 수집에 유리하다. 이런 특징들로 특히 IoT 영역에서 주목받고 있다.


[각주:1]


또한, MQTT의 특징을 살려서 낮은 전력에서 작동하는 Push 서비스를 만들 수 있다. 모바일 애플리케이션을 위한 메시지 Push 서버로 많이 사용되며, 페이스북의 경우 MQTT를 이용해서 메시지를 Push 하고 있다.

Publish/Subscribe(Pub/Sub)

MQTT 프로토콜은 메시지를 발행(publishing)하고 관심있는 주제를 구독(subscribe) 하는 것을 기본 원칙으로 한다. Publisher는 토픽을 발행하기 위해, Subscribe는 토픽을 구독하기 위해 Broker에 대한 클라이언트로 동작한다. 하나 이상의 Pub와 Sub가 브로커에 연결해서 토픽을 발행하거나 구독할 수 있다. 또한 다수의 클라이언트가 하나의 주제를 구돌할 수도 있다.

[각주:2]


토픽(Topic)

Pub/Sub는 Topic을 기준으로 작동한다. Topic은 슬래시(/)를 이용해서 계층적으로 구성할 수 있어서 대량의 센서 기기들을 효율적으로 관리할 수 있다.

아래의 그림은 컴퓨터의 다양한 상태를 측정하는 센서가 있다고 생각할 때는 예시로 표현한 것이다.

QoS(Quanlity of Service)

MQTT는 3단계의 QoS를 제공한다. QoS란 다른 응용 프로그램, 사용장, 데이터 흐름 등에 우선 순위를 정하여, 데이터 전송에 특정 수준의 성능을 보장하기 위한 능력이다.
  • QoS 0: 메시지를 한 번만 전달하고 전달 여부는 확인하지 않음
  • QoS 1: 메시지를 적어도 한 번 이상 전달하고 전달 여부 확인
  • QoS 2: 4단계의 핸드셰이킹(handshaking)을 통해 정화히 한 번만 전달
발행자와 구독자 모두 QoS를 지정할 수 있으나 발행자가 지정한 최대 QoS 수준이 우선시 된다. 예를 들어 아래 그림과 같이 Pub X 가 QoS 수준을 '2'로 지정했다면, 'Sub A'나 'Sub B'는 0, 1, 2 중 어떤 수준으로도 구독할 수 있다.
하지만, 아래 그림과 같이 Pub Y과 QoS 수준을 '0'으로 지정했다면 Sub C가 QoS 2로 구독하려고 할 때 Broker에 의해 막히고 QoS 0으로만 받게된다.

MQTT 지원 서버

MQTT 를 지원하는 서버의 종류는 이곳에 잘 설명되어있으니 링크를 참조하면 된다.

AMQP(Advanced Message Queuing Protocol)

MQ의 오픈소스를 기반으로 한 표준 프로토콜을 의미한다. AMQP 자체는 프로토콜을 의미하기 때문에 이 프로토콜에 따른 실제 MQ 제품들은 여러가지가 존재할 수 있으나 최근 많이 사용되는 것은 아무래도 Erlang과 자바로 작성된 RabbitMQ라고 한다.


AMQP Routing model

AMQP Routing model 은 RabbitMQ 기능 설명으로 대체한다. 이곳에 가면 AMQP에 대한 등장배경 및 설명이 있으니 참고해도 된다. 

RabbitMQ[각주:4]

RabbitMQ는 AMQP(Advanced Message Queuing Protocol)을 구현한 메시지 브로커이다. Cluster 구성이 쉽고 ManageUI 기능이 제공되며 현재 많이 사용되고 있다. 또한 ManagementUI, Autocluster, MQTT Convert, STOMP 등의 plugin도 제공되어 확장성이 뛰어나며 Spring에서도 AMQP 연동 라이브러리가 제공되어 편리하게 연동 가능하다.

특징

  • ISO 표준(ISO/IEC 19464) AMQP 구현
  • 비동기처리를 위한 메시지큐 브로커
  • erlang과 java 언어로 만들어짐 (clustering 등을 위한 고속 데이터 전송하는 부분에 erlang이 사용된 것으로 추정)
  • 분산처리를 고려한 MQ (Cluster, Federation)
  • 고가용성 보장 (High Availability)
  • Publish/Subscribe 방식 지원
  • 다양한 plugin 지원

RabbitMQ (AMQP) 기능

 이름

설명 

그림 

 Producer(생산자)

 메시지를 보내는 application

 


 Publish

 Producer가 메시지를 보냄

 

 Queue

 메시지를 저장하는 버퍼. 

 Queue는 Exchange에 Binding된다.

 


 Consumer 메시지 받는 User application. 
 동일 업무를 처리하는 Consumer는 보통 하나의 Queue를 바라본다. (중복방지)
 동일 업무를 처리하는 Consumer가 여러개인 경우 같은 Queue를 바라보게 하면 자동으로 메시지를 분배하여 전달함
 


 Subscribe Consumer가 메시지를 수신하기 위해 Queue를 실시간으로 리스닝 함 
 Exchange  Producer가 전달한 메시지를 Queue에 전달하는 역할.
 메시지가 Quque에 직접 전달되지 않고 exchange type이라는 속성에 정의된데로 동작
 


 Exchange Type

 특정 Queue에 보낼지, 여러 Queue에 보낼지, 제거될지 등을 선택

  • fanout: 알려진 모든 Queue에 메시지 전달 함 (Broadcast)
  • direct: 지정된 routingKey를 사진 Queue에만 메시지 전달 함 (unicast)
  • topic: 지정된 패턴 바인딩 형태에 일치하는 Queue에만 메시지 전달. #(여러단어), *(한단어)를 통한 문자열 패턴 매칭 (multicast)
  • header: 헤더에 포함된 key=value의 일치조건에 따라서 메시지 전달 (multicast)
 
 Bindings

 Exchange와 Queue를 연결해주는 것

 

 Routing Exchange가 Queue에 메시지를 전달하는 과정  

 RoutingKey

 Exchange와 Queue가 Binding될 때 Exchange가 Queue에 메시지를 전달할지를 결정하는 기준

 Publish RoutingKey가 Binding시 설정된 RoutingKey값과 일치하거나(exchange type=direct) RoutingKey값이 Binding시 설정된 패턴에 매칭될 때(exchange type=topic)

 


기본 흐름

Producer가 메시지를 생성하여 전송 -> Queue가 메시지를 순차적으로 쌓음 -> Consumer가 Queue에 대한 Binding을 가지고 있다가 메시지를 Queue에서 수신

상세 흐름

Producer가 메시지를 생성하여 전송 -> Exchange가 어떤 Queue에 전달할지를 Routing -> Queue들이 메시지를 순차적으로 쌓음 -> Consumer가 Queue에 대한 Binding을 가지고 있다가 메시지를 Queue에서 수신

메시지 분배 (Round-robin dispatching)

RabbitMQ는 (Consumer가 병렬처리를 쉽게 할 수 있도록) 같은 Queue를 바라보고 있는 Consumer에게 메시지를 균등 분배한다. 이것은 MQ의 존재 이유인 중요한 개념이다. 이로 인해 메시지를 받아 처리하는 프로그램들은 수평 확장이 가능하며, 같은 Queue에 메시지를 던져주기만 하면 되므로 Producer도 수평 확장이 가능하다.

-> 첫번째 메시지는 Consumer1에게 두번째 메시지는 Consumer2에게 분배 (중복 방지)

Fair dispatch (공평한 분배)

여러 consumer에게 round robin할 때 번갈아가면서 메시지를 전달하지만 예를들어 데이터 크기가 매홀수는 크고 매짝수는 작은 상황처럼 완벽하게 공평하지는 않다. 따라서 바쁜 Consumer에게 메시지를 계속 보내는 것을 방지하기 위해 prefetchCount라는 개념을 사용한다. prefetchCount란 동시에 보내는 메시지의 양이다. 만약, prefetchCount가 1일 때, 아직 ACK을 받지 못한 메시지가 있다면 그 메시지를 받았던 Consumer에게 다시 메시지를 할당하지 않는다.

Acknowledgement

많은 프로토콜이 메시지 전달 보장은 Acknowledgement(ACK) 개념을 사용하여 응답을 보내준다. MQTT의 경우 0(안보냄), 1(전달완료확인), 2(최종목적지까지 처리완료)인 QoS(Quality of Service) level 확인 개념이 있는데 RabbitMQ에서는 ACK(Consumer전달확인), Confirm(Publish전달확인)을 이용한 level 1만 지원한다고  이곳에서 추정하고 있다.


  1. http://www.joinc.co.kr/w/man/12/MQTT/Tutorial [본문으로]
  2. http://d2.naver.com/helloworld/1846 [본문으로]
  3. http://d2.naver.com/helloworld/1846 [본문으로]
  4. https://github.com/gjchoi/gjchoi.github.io/blob/master/_posts/2016-02-27-rabbit-mq-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0.md [본문으로]

댓글