About MQTT
01 Feb 2019 | IoT포스팅
MQTT
HTTP등 프로토콜을 사용할 때 직면하는 대표적인 문제 중 하나는 바로 방화벽을 뛰어넘는 것이다. 방화벽을 사용하면 들어오는 접속 시도를 차단할 뿐만 아니라 집이나 사무실에 구성된 네트워크를 하나의 IP 주소로만 표현하여 내부에 연결된 장치를 숨겨버린다. 방화벽에서 밖으로 나가는 연결까지 차단하도록 설정되어 있지 않고, 방화벽 안에 있는 모든 엔드포인트가 클라이언트 역할을 하여 방화벽 밖에 있는 메시지 중개자(Broker)를 통해 통신한다면, 모든이와 통신하도록 방화벽을 뛰어 넘을 수 있다. 메시지 중개자는 서버로 구성하지만, 클라이언트 사이의 메시지를 단순히 전달하는 역할만 한다. 이러한 메시지 중개자를 위해 개발된 프로토콜이 바로 MQTT(Message Queue Telemetry Transport)다. Publish/Subscribe 게시/구독 패턴 게시자 Publisher: 메시지 중개자에 연결하여 콘텐츠를 게시한다. 구독자 Subsriber: 게시자처럼 메시지 브로커에 접속하여 원하는 콘텐츠를 구독한다. 메시지 중개자 Message Brocker: 게시된 콘텐츠를 구독자에게 전달한다. MQTT를 통해 게시하고 구독하는 콘텐츠는 토픽(Topic)으로 식별한다. 콘텐츠를 게시할 때, 게시자는 이 콘텐츠를 서버에 남겨둘지 여부를 결정할 수 있다. 서버에 남겨두면, 구독을 신청하자마자 최신 게시물을 받을 수 있다. 이러한 토픽은 파일 시스템처럼 트리 구조로 정렬할 수도 있다. 토픽에 대한 경로를 표현할 때 구분자(delimeter)로 슬래시 문자(/)를 사용한다. 콘텐츠에 구독할 때 원하는 토픽을 구체적인 경로로 지정하거나, 와일드카드 문자로 해시 기호(#)를 사용해 특정한 토픽에 속한 모든 토픽을 통째로 지정할 수 있다. 와일드카드 문자로 플러스 기호(+)를 사용하면, 트리에서 한 층에 대한 토픽만 지정할 수 있다. 이렇게 토픽을 지정하는 방법에 대한 이해를 돕기 위해 예를 들어보자. MQTT 프로토콜은 다음과 같은 구조로 구성된다.<MQTT Protocol Structure>
MQTT에서는 콘텐츠를 게시할 때 QoS 수준을 세 단계로 지정할 수 있다. 가장 낮은 단계인 비확인 서비스(Unacknowledged Service)로 지정하면 메시지를 구독자에게 최대한 한번만 보낸다. 두 번째 단계인 확인 서비스(Acknowledged Service)로 지정하면 게시된 정보를 받았다는 확인 메시지를 받는다. 구독자로부터 확인 메시지를 받지 못하면 다시 보낸다. 이렇게 하면 게시된 정보가 구독자에게 최소한 한 번은 보내도록 할 수 있다. 가장 높은 단계인 보증 서비스(Assured Service)로 지정하면 먼저 전송한 뒤에 전달하는 두 단계를 거치는 방식으로 정보를 보낸다. 이때 각 단계마다 확인 메시지를 받는다. 이렇게 하면 모든 구독자가 콘텐츠를 정확히 한 번만 전달할 수 있다. + MQTT에서는 사용자 인증에 대한 기능이 부족하다. 유저네임과 패스워드를 일반 텍스트로 입력하는 방식으로만 인증하기 때문에, 보안 기능을 갖추지 않은 네트워크에 서버를 설치하면 위험할 수 있다. 이를 보완하기 위해 MQTT에서 암호화된 통신을 하기 위해 SSL/TLS를 사용할 수도 있다. 이때 클라이언트는 반드시 서버 인증서를 검사하여 서버에 대한 자격증명이 손상되지 않았는지 확인해야 한다. MQTT에서 직접제공하는 유저네임과 패스워드를 이용한 인증 방법 대신, 클라이언트 인증서를 사용하거나 미리 공유된 키로 클라이언트를 식별하게 할 수도 있다. 상용 솔루션으로 콘텐츠를 암호화하여 적합한 자격증명을 가진 수신자만 콘텐츠를 복호화할 수 있도록 구성해도 된다. 이렇게 하면 보안의 취약점을 줄일 수 있지만, 상호운용성이 다소 떨어지게 될 뿐만 아니라 각 장치마다 처리해야 하는 작업이 늘어나게 되어, MQTT가 추구하는 바와 상충되는 결과를 초래하게 된다. MQTT에서 자체적으로 보안 기능을 제공하지 않기 때문에, MQTT로 구현하는 개발자가 직접 보안 기능을 제공해야 한다. 사용자 자격증명을 관리하는 기능도 개발자가 직접 구현하거나 상용 솔루션을 활용하여 제공해야 한다. + MQTT에서는 (요청을 보내는 토픽을 별도로 만들어야 하므로) 요청/응답 패턴을 구현하는 것이 쉽지 않다. 따라서 구독자에게 센서가 죽지 않고 잘 동작하고 있다는 사실을 알려주거나 센서로 측정한 값을 알려주려면 별도의 방법을 써야 한다. 한 가지 방법은, 마지막으로 게시한 값에 변화가 없거나 변화량이 미미하더라도, 현재 상태를 일정한 주기로 게시하는 방식으로 구현할 수 있다. + MQTT는 바이너리 프로토콜이므로, 콘텐츠를 인코딩하거나 디코딩하는 기능은 제공하지 않는다. 따라서 인코딩과 디코딩을 직접 알아서 처리해야 한다. + MQTT의 장점 중 하나는 대용량의 데이터를 하나의 메시지로 하나의 토픽에 전송할 수 있다는 점이다. MQTT에서 토픽 콘텐츠의 크기는 256MB로 제한한다. 따라서 멀티미디어 데이터를 여러 세그먼트로 나누거나 스트리밍 방식으로 전송하지 않고도 그대로 게시할 수 있다.