이 론
MQTT(Message Queueing Telemetry Transport)는 2016년 국제 표준화 된 (ISO 표준 ISO/IEC PRF 20922) 발행-구독(Publish-Subscribe) 기반의 메시지 송수신 프로토콜이다.
작은 코드 공간이 필요하거나 네트워크 대역폭이 제한되는 원격 통신을 위해, 즉 IoT와 같은 제한된, 혹은 대규모 트래픽 전송을 위해 만들어진 프로토콜이다. 그렇기에 TCP/IP 프로토콜 위에서 동작하지만 동시에 굉장히 가벼우며, 많은 통신 제약들을 해결해준다.
(그러나 이 말은 동시에 MQTT는 Bluetooth나 Zigbee처럼 별도의 모듈로 별도의 대역폭을 갖는 통신 규약이 아닌, WiFi나 기타 방법을 통해 인터넷을 통해 TCP/IP 기반의 메시지 송수신을 한다는 것을 의미하기도 한다.)
이러한 장점들 때문에 Facebook Messenger가 MQTT를 채택했고, 우아한형제들(배달의 민족 서비스 기업)에서도 중계 시스템 개선을 위해 MQTT를 도입하려 시도한 적이 있었다. (해당 이야기는 후술)
단, Trade-Off는 항상 존재하기 때문에, 메시지가 가벼운 만큼 메시지 유형이나 QoS(서비스 품질)에는 제약이 가해진다.
그렇다면 MQTT의 특장점에 대해 알아보도록 하자.
MQTT의 특징
- 연결지향적 (Connection Oriented)
- MQTT 브로커와 연결을 요청하는 클라이언트는 TCP/IP 소켓 연결을 한 후 명시적으로 연결을 끊거나 네트워크 사정에 의해 연결이 끊어질 때까지 상태를 유지
- Live라는 하트비트와 Topic에 발행되는 메시지를 통해 연결을 유지하고 메시지 송수신을 하게 됨
- 연결이 끊어지면 재접속 가능
- 브로커를 통한 통신
- MQTT의 발행-구독 메시징 패턴은 오로지 브로커를 통해서만 통신할 수 있으며 개설된 Topic에 메시지를 발행하면 해당 Topic을 구독하는 클라이언트들에게 메시지를 발행할 수 있다.
- 그렇기에 일대일, 혹은 일대다의 통신이 모두 가능하다.
- QoS (Quality of Service)
- 0: 최대 1회 전송. Topic을 통해 메시지를 전송할 뿐 보장은 하지 않는다. (보낸 다음 잊어버림)
- 1: 최소 1회 전송. 구독하는 클라이언트가 메시지를 받았는지 불확실하면 정해진 횟수만큼 재전송한다. 메시지의 핸드셰이킹 과정을 엄밀하게 추적하지는 않으므로 중복의 위험성이 있다. (확인 응답을 거치는 전달)
- 2: 구독하는 클라이언트가 요구된 메시지를 정확히 한 번 수신할 수 있도록 보장한다. 메시지의 핸드셰이킹 과정을 추적한다. 높은 품질을 보장하지만 성능의 희생이 따른다. (보장된 전달)
- 이 필드는 기반이 되는 TCP/IP 데이터 전송의 처리에 영향을 주지 않으며, MQTT 송신자와 수신자 간에만 사용된다.
- 메시지는 글자 수 제한이 없으므로, 긴 메시지나 JSON 포맷 또는 파일도 전송이 가능하다.
- 0에 가까울수록 메시지 처리에 대한 부하가 줄어들고, 메시지 손실의 위험이 높아진다. 반대로 2에 가까울수록 메시지 손실 위험을 줄어들지만 메시지 처리 부하가 급격히 늘어난다.
- 단, 0 ~ 1 정도의 QoS를 사용하며 메시지 손실의 위험은 상위 어플리케이션 차원에서 관리하는 방법이 널리 쓰이고 있다.
- 메시지 유형
- 연결하기
- 서버와의 연결 수립을 기다린 다음 노드 간 링크를 만든다.
- 연결 끊기
- MQTT 클라이언트가 해야 할 일을 기다리고 인터넷 프로토콜 스위트 세션의 연결이 끊어지기를 기다린다.
- 발행하기
- MQTT 클라이언트에 요청이 전달된 직후 어플리케이션 스레드에 즉시 반환한다.
- 각각의 메시지의 event에 따라 MQTT 브로커가 Notification을 주어 대응할 수 있도록 한다.
- 연결하기
- 다양한 개발언어의 다양한 클라이언트 지원
- C/C++/Java/Node.js/Python/Arduino 등 여러 종류로 브로커와 라이브러리가 존재한다.
MQTT 동작 구조
토픽 (Topic)
메시지를 발행-구독하는 행위는 채널 단위로 일어난다. 이를 MQTT에서는 토픽이라고 부르고, 토픽은 슬래시(/)로 구분되는 계층 구조를 갖는다.
company / firstFloor / SWoffice / temp
위 예시에서 슬래시 전후에 있는 office, firstFloor, SWoffice, temp는 모두 각각의 토픽 레벨(Topic Level)이며, 해당 토픽은 Topic Level Separator라고 불리는 슬래시로 구분된다.
즉, 위의 토픽은 회사 1층의 SW부서의 온도를 체크할 수 있는 토픽이다.
company / firstFloor / + / temp
위는 메시지를 구독-발행할 때 여러 개의 토픽을 한 번에 지정할 수 있도록 지원하는 와일드 카드의 예시이다.
[+] 문자는 One-Level Wild Card로, 단 한 개의 토픽을 임의의 토픽으로 대체할 수 있다.
즉, 위의 토픽은 회사 1층에 있는 모든 부서의 온도를 체크할 수 있는 토픽이다.
company / firstFloor / #
[#] 문자는 Multi-Level Wild Card로, 여러 레벨의 토픽을 대체할 수 있는 와일드 카드이다.
이는 2단계 이상의 하위 토픽도 대체할 수 있으며, 무조건 맨 마지막에만 사용될 수 있다.
위 예시에서는 회사 1층의 모든 부서의 모든 조건(온도, 습도, 조도 등)을 체크할 수 있는 토픽이다.
$SYS/
[$] 문자로 시작하는 토픽은 시스템에 의해 사용되는 특수한 토픽이다. 이 토픽들은 [#] 문자로 지정해도 포함되지 않으며, 주로 브로커의 내부 메시지를 위해 사용된다.
주의할 점
- 최상위 토픽이 [/] 문자로 시작되지 않아야 한다. 물론 이 자체로 오류가 뜨지는 않지만 최상위 토픽이 이름 없는 토픽이 되어버린다. 즉, [ / company / firstFloor / SWoffice / temp ] 이런 식으로 되지 않아야 한다. 이는 PC의 디렉토리와 비슷하게 생각한다면 흔히 할 수 있는 실수이다.
- 토픽 이름에 공백 문자가 들어가면 안 된다.
- 토픽 이름은 임베디드 IoT 장치와의 호환성을 위해 ASCII 문자만 사용하도록 한다.
- [#] 문자를 이용해서 토픽 전체를 구독하지 않도록 해야 한다. 오버헤드가 심할 경우 브로커/클라이언트 프로세스가 중단될 가능성이 높다.
'IT > 임베디드 IoT' 카테고리의 다른 글
[Buildroot] 임베디드 리눅스 구조의 이해 (11) | 2020.04.29 |
---|---|
[통신 이론] MQTT, MQTT Protocol (MQTT 프로토콜) 이란? - 2 (실전편) (0) | 2020.01.16 |