# MQTT (Message Queuing Telemetry Transport)의 심층 분석

#### MQTT의 개요

MQTT(Message Queuing Telemetry Transport)는 경량의 메시지 프로토콜로, 주로 저전력 장치나 대역폭이 제한된 네트워크 환경에서 사용되도록 설계되었다. MQTT는 브로커-클라이언트 구조를 기반으로 하며, publish/subscribe 모델을 통해 데이터의 전송을 관리한다. 이 프로토콜은 IBM에서 개발되었으며, ISO 표준(ISO/IEC PRF 20922)으로 지정되어 있다.

#### MQTT 프로토콜의 구조

MQTT는 주로 두 가지 주요 구성 요소로 구성된다: 클라이언트와 브로커. 클라이언트는 데이터를 게시하거나 구독하는 역할을 하며, 브로커는 이러한 메시지를 수신, 관리, 배포하는 중앙 허브 역할을 한다.

**클라이언트**

클라이언트는 MQTT 네트워크에서 실제 데이터를 전송하거나 수신하는 장치이다. 클라이언트는 두 가지 주요 역할을 수행할 수 있다:

* **Publisher**: 메시지를 특정 주제(topic)로 브로커에게 전송한다.
* **Subscriber**: 특정 주제를 구독하고, 해당 주제에 게시된 메시지를 브로커로부터 수신한다.

클라이언트는 매우 경량이며, 저전력 환경에서도 동작할 수 있도록 설계되었다. 이를 통해 IoT 장치와 같은 자원이 제한된 환경에서도 효율적으로 통신할 수 있다.

**브로커**

브로커는 MQTT 시스템의 중앙 허브 역할을 한다. 모든 클라이언트의 메시지가 브로커를 통해 전달되며, 브로커는 구독자에게 메시지를 배포하는 역할을 한다. 브로커의 주요 기능은 다음과 같다:

* **메시지 관리**: 브로커는 클라이언트가 전송한 메시지를 수신하고, 적절한 구독자에게 이를 전달한다.
* **세션 관리**: 브로커는 클라이언트의 세션을 관리하며, 특히 클라이언트가 연결이 끊긴 후에도 QoS 설정에 따라 메시지를 유지하거나 재전송할 수 있다.
* **보안 관리**: 브로커는 인증 및 권한 부여를 통해 클라이언트 간의 안전한 통신을 보장할 수 있다.

#### MQTT의 QoS (Quality of Service)

MQTT는 메시지 전송의 신뢰성을 보장하기 위해 세 가지 QoS 레벨을 제공한다. 각 QoS 레벨은 메시지 전송의 보장 정도에 따라 다르다.

**QoS 0: At most once**

이 레벨에서 메시지는 한 번만 전송되며, 재전송되지 않는다. 브로커와 클라이언트는 메시지가 성공적으로 전달되었는지 확인하지 않으며, 네트워크 오류나 기타 문제로 인해 메시지가 손실될 수 있다. 이 방법은 가장 적은 오버헤드를 가지며, 높은 속도가 요구되는 상황에서 적합하다.

**QoS 1: At least once**

이 레벨에서는 메시지가 최소 한 번 이상 전달된다. 클라이언트는 브로커로부터 PUBACK(전송 확인) 메시지를 수신할 때까지 메시지를 재전송한다. 이로 인해 메시지가 중복 전송될 수 있지만, 메시지 손실의 가능성은 줄어든다.

**QoS 2: Exactly once**

가장 높은 신뢰성을 제공하는 QoS 레벨로, 메시지는 정확히 한 번만 전달된다. 이 레벨에서는 네 단계의 핸드셰이크 과정을 거쳐 메시지 중복이나 손실이 발생하지 않도록 보장한다. 그러나 이는 가장 높은 오버헤드를 발생시킨다.

#### MQTT의 메시지 구조

MQTT 메시지는 다양한 필드를 포함하고 있으며, 각각의 필드는 메시지의 유형과 기능에 따라 다르게 구성된다.

**고정 헤더 (Fixed Header)**

모든 MQTT 메시지는 고정 헤더를 포함한다. 고정 헤더는 메시지의 타입과 특정 플래그를 나타내며, 이는 2바이트로 구성된다.

* **메시지 타입**: MQTT에서 정의된 메시지 타입은 CONNECT, PUBLISH, SUBSCRIBE, UNSUBSCRIBE, DISCONNECT 등 다양한 메시지 타입이 있다.
* **플래그**: 메시지 타입에 따라 추가적인 플래그가 설정된다. 예를 들어, PUBLISH 메시지의 경우, DUP, QoS, RETAIN 플래그가 설정될 수 있다.

**가변 헤더 (Variable Header)**

일부 메시지 타입에서는 가변 헤더를 포함하며, 이는 메시지의 타입에 따라 달라진다. 예를 들어, PUBLISH 메시지에서는 주제 이름(topic name)이 가변 헤더에 포함된다.

**페이로드 (Payload)**

페이로드는 실제 데이터가 포함되는 부분이다. PUBLISH 메시지의 경우, 페이로드는 브로커를 통해 전송될 실제 메시지 내용을 담고 있으며, SUBSCRIBE 메시지의 경우에는 클라이언트가 구독하고자 하는 주제 목록을 포함한다.

#### MQTT의 유지 연결 및 상태 관리

MQTT는 항상 연결 상태를 유지하며, 클라이언트와 브로커 간의 연결이 끊겼을 때 자동으로 재연결을 시도한다. 이와 관련하여 MQTT는 **Keep Alive**와 **Last Will and Testament (LWT)** 등의 메커니즘을 제공한다.

**Keep Alive**

Keep Alive는 클라이언트가 일정 간격으로 브로커에게 PINGREQ 메시지를 보내어 연결 상태를 유지하도록 한다. 만약 브로커가 설정된 시간 내에 이 메시지를 수신하지 못하면, 클라이언트가 비정상적으로 종료되었음을 감지하고 연결을 끊는다.

**Last Will and Testament (LWT)**

LWT는 클라이언트가 비정상적으로 연결이 끊어졌을 때, 브로커가 특정 주제에 미리 정의된 메시지를 게시하도록 설정할 수 있다. 이는 클라이언트의 상태를 다른 구독자에게 알리는 데 유용하다.

#### MQTT의 보안

MQTT는 본질적으로 경량 프로토콜로 설계되었지만, 다양한 보안 메커니즘을 통해 안전한 통신을 보장할 수 있다.

**TLS/SSL**

MQTT는 TLS/SSL을 통해 전송 계층 보안을 제공할 수 있다. 이를 통해 클라이언트와 브로커 간의 통신은 암호화되어 도청이나 중간자 공격을 방지할 수 있다.

**인증 및 권한 부여**

MQTT는 클라이언트 인증을 위해 사용자 이름과 비밀번호를 사용하는 기본 인증 메커니즘을 제공한다. 더 나아가, MQTT 브로커는 특정 클라이언트에게 주제에 대한 접근 권한을 부여하거나 제한할 수 있다.

**메시지 보안**

MQTT는 기본적으로 페이로드에 대한 보안을 제공하지 않지만, 응용 계층에서 데이터 암호화를 통해 메시지 자체의 보안을 강화할 수 있다.

***

관련 자료:

* MQTT Version 3.1.1 Specification, OASIS, 2014.
* Gastón C. Hillar, Hands-On MQTT Programming with Python, Packt Publishing, 2018.
* Andrew Banks, Rahul Gupta, MQTT Security Fundamentals, IBM Developer, 2019.
