MQTT(메시지 큐잉 텔레메트리 트랜스포트, Message Queuing Telemetry Transport)는 ISO 표준 Publish(발행)-Subscribe(구독) 기반의 메시징 프로토콜이다. MQTT는 TCP/IP 프로토콜 위에서 동작하는데 이는 Bluetooth나 Zigbee와 같이 다른 통신 모듈이 필요한 것이 아닌 wifi나 lte를 이용해 인터넷을 통해 통신이 이루어진다는 뜻이다. 다만 HTTP, TCP등의 통신과 같이 Server-Client 구조로 이루어지는 것이 아니라 Broker, Publisher, Subscriber 구조로 이루어진다. "작은 코드 공간"(small code footprint)이 필요하거나 네트워크 대역폭이 제한되는 원격 위치와의 연결을 위해 설계되어 있다. Publish-Subscribe 메시징 패턴은 메시지 브로커(Broker)가 꼭 필요하다. Publisher는 Topic을 publish 하고 Subscriber는 Topic에 subscribe한다. Broker는 이들을 중계하는 역할을 하며, 단일 Topic에 여러 Subscriber가 구독할 수 있기 때문에 해당 Topic을 구독하는 클라이언트들에게 메시지를 발행할 수 있다. 그렇기에 일대일, 혹은 일대다의 통신이 모두 가능하다.
또 다른 MQTT의 특징은 연결지향적(Connection Oriented)이라는 것이다. MQTT 브로커와 연결을 요청하는 클라이언트는 TCP/IP 소켓 연결을 한 후 명시적으로 연결을 끊거나 네트워크 사정에 의해 연결이 끊어질 때까지 상태를 유지
Live라는 하트비트와 Topic에 발행되는 메시지를 통해 연결을 유지하고 메시지 송수신을 하게 된다. 또한 연결이 끊어지면 재접속 가능하다.
Topic
MQTT에서 메시지를 발행-구독하는 행위는 채널 단위로 일어난다. 이를 토픽이라고 부르고, 토픽은 슬래시(/)로 구분되는 계층 구조를 갖는다. Topic의 예시는 아래와 같다.
food/asia/east/korea
위 예시에서 슬래시 전후에 있는 food, asia, east, korea은 모두 각각의 토픽 레벨(Topic Level)이며, 해당 토픽은 Topic Level Separator라고 불리는 슬래시(/)로 구분된다. 즉, 위의 예시는 음식 중 한식을 체크할 수 있는 토픽이다.
food/asia/east/+
위는 메시지를 구독-발행할 때 여러 개의 토픽을 한 번에 지정할 수 있도록 지원하는 와일드 카드의 예시이다. [+] 문자는 One-Level Wild Card로, 단 한 개의 토픽을 임의의 토픽으로 대체할 수 있다. 위 토픽은 동아시아의 모든의 음식을 확인할 수 있는 토픽이다.
food/asia/#
[#] 문자는 Multi-Level Wild Card로, 여러 레벨의 토픽을 대체할 수 있는 와일드 카드이다. 이는 2단계 이상의 하위 토픽도 대체할 수 있으며, 무조건 맨 마지막에만 사용될 수 있다. 위 예시는 아시아 음식의 모든 것을 체크할 수 있는 토픽이다.
$SYS/
[$] 문자로 시작하는 토픽은 시스템에 의해 사용되는 특수한 토픽이다. 이 토픽들은 [#] 문자로 지정해도 포함되지 않으며, 주로 브로커의 내부 메시지를 위해 사용된다.
또한 Topic 생성시 주의할 점이 있다.
우선 최상위 토픽이 [/] 문자로 시작되지 않아야 한다. 만약 [/food/asian/korean]과 같은 방식으로 설계되면 최상위 토픽이 이름 없는 토픽이 된다.
또한 토픽 이름에 공백 문자가 들어가면 안 된다. 토픽 이름은 임베디드 IoT 장치와의 호환성을 위해 ASCII 문자만 사용하도록 한다.
마지막으로 [#] 문자를 이용해서 토픽 전체를 구독하지 않도록 해야 한다. 오버헤드가 심할 경우 브로커/클라이언트 프로세스가 중단될 가능성이 높다.
메세지 유형
MQTT는 아래 세가지 메세지 유형이 존재한다.
1. 연결하기(Connect)
서버와의 연결 수립을 기다린 다음 노드 간 링크를 만든다.
2. 연결 끊기(Disconnect)
MQTT 클라이언트가 해야 할 일을 기다리고 인터넷 프로토콜 스위트 세션의 연결이 끊어지기를 기다린다.
3. 발행하기(Publish)
MQTT 클라이언트에 요청이 전달된 직후 애플리케이션 스레드에 즉시 반환한다.
QoS
브로커에 대한 각 연결은 QoS(Quality of Service) 기준을 지정할 수 있다. 부하가 늘어나는 순서에 따라 다음과 같이 총 3단계로 나뉘어져 있다.
0 : 최대 한 차례
메시지는 한 번만 보내면 클라이언트와 브로커는 전달 확인 응답을 위한 추가 단계를 밟지 않는다. (보낸 다음 잊어버림)
1 : 최소 한 차례
메시지는 확인 응답을 수신할 때까지 여러 번 송신자로부터 재시도된다. (확인 응답을 거치는 전달)
2 : 정확히 한 번
송신자와 수신자는 2단계 핸드셰이크에 참여함으로써 오직 하나의 메시지 사본만을 수신하는 것을 보장한다.
이 필드는 기반이 되는 TCP 데이터 전송의 처리에 영향을 주지 않으며, MQTT 송신자와 수신자 간에만 사용된다.
QoS의 단계가 높아질 수록 통신의 품질은 향상되지만 그에 따라 trade-off가 있어 성능이 저하될 가능성이 있으므로. MQTT의 QoS는 프로젝트의 특성에 따라 결정되되어야 한다. 다만 0~1 정도의 QoS를 사용하며 메시지 손실의 위험은 상위 어플리케이션 차원에서 관리하는 방법이 널리 쓰이고 있다고 한다.
MQTT 프로토콜을 구현하는 브로커들은 아래와 같이 여러 것들이 있다.
- Mosquitto
- HiveMQ
- mosca
- ActiveMQ
- RabbitMQ (Plug-in 형태로 지원)
또는 Mobius라는 개방형 IoT 플랫폼을 이용해 MQTT 방식으로 서비스를 구현할 수 있다.
참고 자료
https://ko.wikipedia.org/wiki/MQTT
https://medium.com/@jspark141515/mqtt%EB%9E%80-314472c246ee
https://underflow101.tistory.com/22?category=826163