12 MQTT
페이스북 메신저에 사용된 MQTT
페이스북 메신저를 살펴볼 수 있겠습니다. 페이스북에서 배포한 안드로이드용 메신저 앱은 MQTT 푸시 서비스가 백그라운드에서 실행됩니다. 이렇게 하면 주기적으로 폴링(polling)하는 데 비해 배터리 및 패킷 소모량이 적다는 장점이 있습니다. 또한, 페이스북은 일반적인 채팅 서비스 방식을 도입하지 않았는데, 이는 수억 명의 사용자를 보유한 페이스북 서비스의 경우, 서버에 세션을 만들고 세션에 참여한 사용자를 관리하는 것만으로도 상당량의 서버 부하가 발생할 수 있기 때문입니다. 그 대신 MQTT를 도입하여 각 채팅방을 하나의 토픽으로 지정하고, 채팅에 참여한 사용자를 각각 발행자와 구독자로 메시지를 전달하게 한 뒤, MQTT 브로커가 메시지 전달을 책임지게 하는 것으로, 세션 관리에 대한 부하를 분산하였습니다. 웹과 비교했을 때 모바일 환경에서는 3G 연결이 자주 끊기고 재전송이 빈번하게 발생하는데 MQTT의 발행/구독 구조로 구현하면 웹 사용자가 모바일 사용자에게 발행한 메시지를 모바일 사용자가 연결되는 시점에 브로커가 푸시하도록 구현할 수 있다는 장점이 있습니다. 이렇게 하면 채팅 참여자는채팅방 토픽을 구독하고 채팅을 시작하면 토픽을 발행하다가 채팅방을 떠날 때 구독을 해제하기만 하면 됩니다. 페이스북 담당자는 수억 명의 회원이 가입한 페이스북 서비스에서 수많은 사용자가 동시에 메시지를 전송하더라도 짧은 시간 내에 메시지가 전송될 수 있는 구조를 개발하는 데 주력했으며, 이를 위해 MQTT 프로토콜 방식을 MQTT
방식의 도입을 통해 수 초 걸리던 휴대폰과 휴대폰 사이의 전송 속도를 수백 밀리 초로 단축할 수 있었다고 합니다.
MQTT의 이해
1. MQTT의 개념
MQTT의 이해
MQTT에 대해 알아보도록 하겠습니다. MQTT란 Message Queuing Telemetry Transport의 약자로, 원격 제어, 원격 측정을 위한 통신 프로토콜을 말합니다. 원격 검침기는 대부분 소형이며 통신 대역폭과 전원이 한정적인 환경에서 동작하는데, 이는 배터리 용량이 제한적이고 통신 품질을 일정 수준으로 유지하기 어렵다는 점에서 스마트폰 환경과 매우 유사합니다.
사물인터넷 시대가 열리면서, 원격 검침기의 Telemetry는 사물을 뜻하는 Thing으로 그 영역을 확장시켜 나가고 있습니다.
MQTT의 역사에 대해 살펴보겠습니다. IBM의 앤디 스탠포드 클락과 알렌 니퍼에 의해 처음 발명되어, 1999년 초기 버전이 발표되었습니다. 이후 10년 이상 유지 발전해 오면서 센서와 장치 모바일 기기들의 연결을 위한 프로토콜로 자리를 잡아갔습니다.
2004년 MQTT.org에 스펙 및 클라이언트 라이브러리를 공개하였고, 2012년 이클립스 오픈소스 M2M 워킹그룹 내의 M2M 프로젝트였던 파호에 MQTT 클라이언트 라이브러리를 공여합니다. 2013년 이후에는 대용량 메시지 전달 프로토콜로 글로벌 표준화 컨소시엄에서 관리하는 OASIS(Organization for the Advancement of Structured Information Standards)에 의해 사물인터넷 표준 프로토콜로서 선정되었습니다.
2. MQTT의 특징
MQTT의 특징을 알아보도록 하겠습니다. MQTT의 특징은 요구조건, 경량화, 유연성과 확장성, 생산성, 네 가지로 나누어 살펴볼 수 있습니다.
먼저 요구조건은 실시간 푸시 전송을 하면서도 전력사용은 최소화하며 비동기 메시징과 신뢰성이라는 특징을 지닙니다. 경량화는 경량 메시지 포맷을 사용하며, 80~100 Kb 정도 코드 메모리만 사용하므로 간단한 구현이 가능합니다.
다음으로 유연성과 확장성 부분에서는 이벤트 방식을 사용하여 다수의 사용자와 디바이스를 지원하며, 응용코드의 변경 없이도 기능 확장이 가능하다는 특징이 있습니다. 마지막으로 생산성 부분에서는 탐지, 저장, 전달, 발행/구독 기능을 제공하는데, 별도의 응용 로직이 필요 없고, 간단한 개념으로 만들어지므로 개발자의 학습이 용이합니다.
3. MQTT의 구조
MQTT의 구조에 대해 학습하도록 하겠습니다. MQTT는 발행/구독 방식의 메시지 큐(Message Queue)로, 원격 검침기가 측정한 데이터를 송신하고 수신하기 위해 그림과 같이 발행자, 토픽, 브로커, 구독자로 구성됩니다. 일반적인 구조는 발행자가 토픽을 발행하면 브로커가 이를 중개하고, 구독자는 브로커를 통해 관심 있는 토픽을 구독하는 것입니다. 발행자와 구독자가 직접 메시지를 주고받지 않기 때문에 비동기 방식이면서, 메시지 큐 방식, 발행/구독, 혹은 출판/가입 방식이라고도 합니다.
오늘의 핫 이슈! 오늘의 핫 이슈는 화분을 관리하는 앱입니다.
화분의 센서가 온도, 습도, 조도에 대한 데이터를 만들어 토픽을 발행합니다. 발행된 토픽은 라즈베리파이를 통해 MQTT 브로커에 전달됩니다. 그리고 브로커는 화분관리 앱을 설치한 스마트폰으로 토픽을 전달하여, 사용자는 화분이 발행한 토픽을 구독합니다. 사용자는 구독된 토픽으로 화분의 정보를 알고 관리할 수 있습니다. 스마트폰 앱으로 토픽을 발행하면, MQTT브로커에 전달이 되고, 브로커는 다시 라즈베리파이 통신을 통해 하드웨어인 아두이노에 전달합니다.
신호를 받은 아두이노가 조명을 ON/OFF하는 등 화분관리에 필요한 동작을 하게 됩니다.
토픽에 대해 살펴보겠습니다. 발행과 구독은 토픽을 기준으로 작동합니다. 토픽은 슬래시(/)를 이용해서 계층적 구조를 가지는데, 주제들을 파일 시스템 형식으로 나눌 수 있어서 좀 더 효율적인 관리가 가능합니다. 예를 들어, 컴퓨터의 다양한 상태를 측정하는 센서를 토픽으로 구성한다면, 센서 / 노드 / 온도나 입출력 등의 센싱 데이터의 종류, / 컴퓨터 부품이나 데이터 연결 상태 등의 계층을 만들 수 있습니다. MQTT는 메시지 버스 시스템입니다. MQTT 브로커가 메시지 버스를 만들고 발행자들로 받은 메시지를 여기에 흘려보내면, 버스에 붙은 애플리케이션들이 메시지를 읽어갑니다.
메시지 버스에는 다양한 주제의 메시지들이 흐를 수 있는데, 메시지를 구분하기 위해서 토픽을 이름으로 하는 메시지 채널을 만드는 것입니다.
따라서 구독자들은 자신이 원하는 토픽만을 선택하여 메시지를 전달받을 수 있습니다. QoS는 Quality of Service의 약자로, MQTT에서 발행/구독되는 메시지의 신뢰성을 위해 제공되며, 이로 인해 반드시 전달되어야 하는 중요 메시지에 대한 전달을 보장하고 있습니다. QoS에는 0, 1, 2 세 가지 레벨이 있는데, QoS 0 레벨은 메시지가 최대 1번 전달되며, 전달 여부는 확인하지 않기 때문에 유실 가능성 있습니다. QoS 1 레벨은 메시지가 최소 1번 전달되며, 전달 여부를 확인하지만, 중복 전달 가능성이 있습니다. QoS 2 레벨은 메시지가 단 한 번, 정확하게 전달됩니다.
QoS는 발행자와 구독자 모두 지정할 수 있습니다. 예를 들어 발행자가 QoS 수준을 '2'로 지정했다면, 구독자는 0, 1, 2 중 어떤 수준으로도 구독할 수 있습니다. 이때 발행자가 지정한 최대 QoS 수준이 우선시됩니다. 발행자가 QoS 수준을 '0'으로 지정했다면, 구독자가 QoS 수준을 2로 지정한다 하더라도 이는 브로커에 의해 무시되고 'QoS 0' 수준의 서비스를 받게 됩니다.
MQTT는 QoS 외에도 클라이언트와 서버 간의 연결을 잃었을 때 이를 보정하기 위한 자체 기능을 갖추고 있습니다. 먼저, Last Will And Testament는 클라이언트가 예고 없이 연결을 잃을 경우에, 서버에서 이벤트가 발생합니다. 이로 인해 서버 측에서 연결의 유실 여부를 인지할 수 있습니다. 장기 구독(Durable Subscription)은 서버에 클라이언트의 구독 정보를 저장해서 세션을 종료하고 난 후, 재접속 시에도 재작업 없이 발행/구독이 유지됩니다. 마지막으로 클린 세션(Clean Session) 기능이 있는데,
이것은 연결 해제 후 다시 연결되었을 때의 이전 세션을 유지하거나 삭제하도록 선택할 수 있습니다.
4. MQTT의 포맷 분석
MQTT의 포맷 분석에 대해 살펴보도록 하겠습니다. MQTT 메시지 포맷은 고정 헤더, 가변 헤더, 페이로드 세 가지로 나뉩니다.
고정 헤더는 메시지의 유형을 정의하며, 가변 헤더는 가변적인 요소가 포함된 명령을 사용합니다. 페이로드는 실제 메시지를 담을 수 있는 곳입니다.
고정 헤더를 살펴볼까요? 고정 헤더는 두 개의 byte로 구성되며, 메시지 타입(Message Type), 플래그(Flag), QoS 레벨, Remaining Length를 정의합니다. 메시지 타입은 0에서 3, 4개의 비트를 이용해서 메시지 타입을
정의하며, 아래와 같이 14가지 유형이 있습니다.
플래그(Flag)는 각각의 비트 포지션에 DUP, QoS, RETAIN을 표시합니다. DUP 플래그는 메시지가 중복된 메시지인지, 처음 보낸 메시지인지를 표시합니다. 또한 2개의 bit를 조합해서 QoS 레벨을 조정할 수 있습니다.
QoS 레벨 별로 메시지 전송을 살펴보면, QoS 레벨 0의 경우에는 우선, 클라이언트가 QoS 수준이 0인 발행 메시지를 서버에 보냅니다. 서버는 토픽에 가입된 가입자에게 수신한 발행 메시지 큐의 메시지를 전달합니다. 클라이언트는 구독자의 수신 여부와는 상관없이 메시지 전송을 완료합니다.
QoS 레벨 1의 경우, 클라이언트는 발행자로부터 받은 메시지를 저장하고, 그것을 QoS 1레벨로 전달합니다. 서버는 메시지를 저장함과 동시에 구독자에게 게시합니다. 메시지 전송이 완료되면, 서버는 발행 완료 응답메시지를 클라이언트에게 전송합니다.
이 메시지를 받은 클라이언트는 전송이 완료된 것으로 판단합니다. 구독자는 메시지 잘 받았는지 여부를 서버에 위임하고, 클라이언트는 서버의 PUBACK 메시지만 체크하는 것입니다.
QoS 레벨 2의 경우, 발행된 메시지의 흐름은 어떻게 될까요? QoS 레벨 0, 1과 마찬가지로 클라이언트는 메시지를 저장, 발행 합니다. 서버 역시 이를 전달받아 구독자에게 게시합니다. 이후에 서버는 PUBREC 메시지를 클라이언트에게 전달하는데, 이것은 발행된 메시지가 접수되었으며 이를 보장한다는 의미입니다. 신호를 받은 클라이언트는 바로 메시지 전송을 완료하지 않고, PUBREL, 즉 발행된 메시지에 대한 보장 배달을 서버에 재요청합니다. 이를 받은 서버는 구독자가 메시지 확인을 한 후에 메시지
전송을 완료하며, 이를 클라이언트에게 알립니다. 클라이언트는 이 모든 과정이 끝난 뒤에 전송을 완료합니다. QoS 레벨 2인 경우, 서버에 있는 메시지 큐의 메시지를 클라이언트가 삭제하는 절차가 추가되어, 서버로부터 발행이 완료되었다는 확인 메시지를 받은 후에서야 전송을 완료시키기 때문에 최상의 품질의 전송을 보장합니다.
Remaining Length는 남은 길이라는 뜻으로, 전체 메시지의 크기를 계산하기 위해서 사용합니다. 즉, 고정 헤더 외의 다른 헤더, 가변헤더와 페이로드의 길이를 더한 값을 삽입하여 메시지의 정보를 넣어주는 것입니다.
1에서 부터 4바이트를 사용하는데, 데이터의 크기에 따라서 가변적입니다. MQTT가 다룰 수 있는 최대 메시지의 크기는 256메가 바이트로 제한됩니다.
가변 헤더에 대해 알아보겠습니다. 어떤 MQTT 명령들은 가변 헤더 요소를 포함하고 있습니다. 가변 헤더는 고정헤더와 페이로드 사이에 존재하며, 각 기능에 따라 조금씩 달라지는 특성이 있습니다. 가변 헤더에는 프로토콜의 이름과 버전, 토픽 이름이 포함됩니다.
프로토콜 이름은 MQTT CONNECT메시지에서 사용되며, UTF-8 인코딩된 프로토콜 이름이 사용됩니다. 프로토콜 버전 역시 MQTT CONNECT메시지와 함께 사용되며, 8bit Unsigned 값을 이용해서 프로토콜 버전을 설정할 수 있습니다. 토픽 이름은 MQTT PUBLISH 메시지에 포함되며, 페이로드에 포함된 데이터를 발행 할 때 사용하는 채널의 이름입니다. MQTT 메시지 포맷의 마지막은 페이로드입니다. 페이로드는 탑재 화물이라는 의미로 실제 전송되는 메시지를 말합니다.
MQTT의 응용
1. 메시지 시퀀스(Message Sequence)
MQTT의 응용
MQTT의 메시지 시퀀스를 알아보도록 하겠습니다. 먼저 단기 구독의 경우, 클라이언트와 서버는 다음과 같은 메시지를 주고받게 됩니다. MQTT 연결 메시지와 연결종료 메시지로 세션이 시작하여 종료됩니다. 특정 토픽에 대하여 가입 시작과 종료는 세션 수명 주기 내에서 구독 요청메시지와 구독 종료메시지로 시작되어 가입 수명 주기를 이룹니다. 구독 수명 주기 안에서 발행 메시지가 토픽으로 또는 토픽부터 전송됩니다.
장기 구독의 경우를 살펴보겠습니다. 단기 구독의 경우와 마찬가지로 클라이언트와 서버 사이에는 접속 요청에서부터 접속 종료 요청까지 메시지가 오갑니다. 차이가 있다면, 이미 구독 중인 상태에서 세션이 생성되고 종료되는 경우도 있습니다. 이것은 클라이언트와 서버 간의 연결을 잃었을 때 이를 보정하기 위한 기능으로 사용됩니다.
서버에 클라이언트의 구독 정보가 저장되므로 세션 종료 후 재접속 시에도 재작업 없이 발행/구독을 유지할 수 있기 때문입니다.
Keep Alive 타이머를 살펴보겠습니다. 서버는 클라이언트로부터 설정된 시간 이상 메시지가 오지 않으면 연결을 해지하는데, 이것을 Keep Alive 타이머라고 합니다. 일반적으로 수 분의 시간을 사용합니다. 발행 메시지가 없는 경우, 연결을 유지하기 위하여 클라이언트는 핑 메시지를 전송합니다. 이 메시지가 도착하면 타이머가 다시 시작되면서 연결이 유지됩니다. 이를 그림으로 나타내면 다음과 같습니다. 메시지가 발행되면 그로부터 일정 시간 연결을 유지합니다. 이것을 Keep Alive 주기라고 합니다. 이 주기 사이에 메시지가 발행되면 서버는 연결 상태를 유지하는 반면, Keep Alive 주기가 지나도록 메시지 발행이
없으면 연결을 해지합니다. 이때 클라이언트는 발행 메시지를 대신하여 핑 메시지를 전송하는데, 발행 메시지와 같은 효과를 냅니다.
MQTT Will 메시지를 살펴보겠습니다. 클라이언트가 서버에 연결할 때 Will 플래그를 세팅하면, 서버는 클라이언트가 연결 종료되었을 때 모든 관련 구독자에게 Will 메시지를 전달하여 해당 클라이언트의 연결 상태를 알리는 것을 말합니다. 이를 그림을 통해 살펴보면, 우선 클라이언트는 서버에 연결할 때 Will 플래그를 설정해 둡니다. 서버는 받은 메시지를 저장하고, 정상적으로 메시지를 수신, 발행하다가 예기치 못한 접속 장애로 인해 연결이 끊어지면, 서버에서 구독자에게 Will 메시지를 발행하여 클라이언트의 연결상태를 알리는 것입니다.
2. 전송 계층
MQTT의 전송계층에 대해 알아보겠습니다. MQTT는 TCP 같은 전송 계층 위에 있는 클라이언트 서버 통신 프로토콜입니다.
클라이언트는 토픽을 출판하거나 토픽에 대하여 가입하여 서버에게 토픽을 받는 역할을 합니다. 서버는 특별히 브로커로서 토픽과 가입자를 관리합니다. 그리고 그 위에는 온도 센서와 같은 응용계층이 자리 잡고 있습니다.
MQTT는 다양한 전송계층 위에서 동작하는 응용 프로토콜입니다. HTTP, TCP와 마찬가지로 전송 순서가 있고, 전송을 보장하는 전송 계층 위에서 동작하도록 되어 있습니다. MQTT는 계층 구조상 TCP/UDP 같은 4계층 전송계층 위쪽에 위치하고 있습니다.
1, 2 계층을 살펴보겠습니다. MQTT는 무선센서 네트워크가 하부구조에 있어야 하는데, IEEE 802.15.4 표준은 지그비가 사용하는 1, 2계층의 무선 전송 기술 MQTT의 하위 계층을 이룰 것입니다. 무선 랜이나 다른 무선 팬 기술이 있지만, 저전력, 대규모, 저가격의 목표를 이루기 위한 요구조건에 맞게 하려면, 1, 2계층부터 적합한 기술을 사용하여야 합니다.
3계층인 IPv6/RPL를 보면, IETF는 네트워크 계층 라우팅 프로토콜을 많이 표준화하고 있는데, 특히 LLNs(Low power and Lossy Networks)은 저전력,
손실 허용하는 네트워크에 사용하는 RPL 라우팅 프로토콜의 표준을 관리합니다. 자원의 제약이 많은 노드들이 많이 연결되는 네트워크 즉, 홈/빌딩/공장 자동화 같은 환경에서 요구하는 여러 가지 라우팅 프로토콜이 3계층의 주제입니다.
8bit 마이컴, 16Kb 메모리를 가진 제약이 많은 환경에서 네트워크 스택이 올라갑니다.
Atmel사의 마이컴과 같은 저사양 컴퓨터에 네트워크 스택과 시스템이 올라갈 정도로 경량의 소프트웨어 환경에서 MQTT의 응용이 돌아갑니다.
MQTT는 다양한 구현들이 존재합니다. MQTT 서버와 클라이언트로 나누어 살펴볼 수 있습니다. 서버로는 Mosquitto, RSMB, ActiveMQ, Apollo 등이 있으며, 클라이언트로는 파호, Xenqtt, Mqtt.js 등이 대표적입니다. 모두 오픈 소스들이고, C언어나 자바스크립트 언어 등으로 구현되어 사용환경에 적절한 것을 선택할 수 있습니다.
'사물인터넷' 카테고리의 다른 글
14 개방형 도구 - 오픈 API (0) | 2016.02.10 |
---|---|
13 CoAP (1) | 2016.02.07 |
11 개방형 플랫폼 - 블루믹스(클라우드 서비스) (0) | 2016.02.02 |
11 개방형 플랫폼 -클라우드 서비스 (0) | 2016.02.01 |
10 개방형 플랫폼 - Node-RED 트위터 감정기반 분석 프로젝트 (0) | 2016.02.01 |