Published on

MQTT 요약 정리하기

Authors
  • avatar
    Name
    JaeHyeok CHOI
    Twitter
    none

MQTT - Message Queue Telemetry Transport

머신 대 머신 통신에 사용되는 표준 기반 메시징 프로토콜 또는 규칙 세트이다.

작은 코드 공간이 필요하거나 네트워크 대역폭이 제한되는 원격 통신을 위해 IoT와 같이 제한되거나 대규모 트래픽 전송을 위해 만들어진 프로토콜이다. 그렇기에 TCP/IP 프로토콜 위에서 동작하지만 동시에 굉장히 가벼우며 많은 통신 제약들을 해결해준다.

(BT나 Zigbee처럼 별도의 모듈로 별도의 대역폭을 갖는 통신규약이 아닌, Wi-Fi와 같은 인터넷을 통해 TCP/IP 기반의 메시지 송수신을 한다.)

mqtt-publish-subscribe.png

개요

MQTT 프로토콜은 메시지 브로커와 여러 클라이언트라는 두 가지 유형의 네트워크 엔티티를 정의한다.

MQTT 브로커는 클라이언트로부터 모든 메시지를 수신한 다음 해당 대상 클라이언트로 메시지를 라우팅하는 서버이다. MQTT 클라이언트는 MQTT 라이브러리를 실행하고 네트워크를 통해 MQTT 브로커에 연결하는 모든 장치이다. (MCU ~ 완전한 서버)

정보는 Topic의 계층 구조로 구성된다. Publisher가 배포할 새 데이터 항목이 있으면 연결된 브로커에 데이터가 포함된 제어 메시지를 보낸 후 브로커는 해당 Topic을 구독한 모든 클라이언트에게 정보를 배포한다. 게시자는 구독자의 수나 위치에 대한 데이터가 필요치 않으며 구독자는 게시자에 대한 데이터로 구성될 필요가 없다.

브로커가 현재 구독자가 없는 토픽에 대한 메시지를 수신하는 경우 메시지 게시자가 해당 메시지를 보존 메시지로 지정하지 않는 한 브로커는 해당 메시지를 삭제한다. 보존 메시지는 보존 플래그가 true로 설정된 일반 MQTT 메시지이다. 브로커는 선택한 토픽에 대한 마지막 보존 메시지와 해당 QoS를 저장한다. 보관 메시지의 토픽과 일치하는 토픽 패턴을 구독하는 각 클라이언트는 구독한 직후 보존 메시지를 수신한다. 브로커는 토픽당 하나의 보존 메시지만을 저장한다.

게시 클라이언트가 처음 브로커에 연결할 때, 브로커가 게시 클라이언트와 브로커의 연결이 예기치 않게 끊어졌음을 감지하면 구독자에게 전송할 기본 메시지를 설정할 수 있다.

클라이언트는 브로커와만 상호작용하지만 시스템에는 현재 구독자의 토픽에 따라 데이터를 교환하는 여러 브로커 서버가 포함될 수 있다. (?)

최소 MQTT 제어 메시지는 2바이트의 데이터만큼 작을 수 있다. 제어 메시지는 필요한 경우 약 256메가바이트의 데이터를 전달할 수 있다. 클라이언트와 브로커를 연결 및 연결 해제하고 데이터를 게시하고, 데이터 수신을 확인하고, 클라이언트와 서버 간의 연결을 감독하는 데 사용되는 정의된 메시지의 유형은 14가지가 있다.

MQTT는 일반 텍스트 형식으로 어떠한 연결 자격 증명, 보안, 인증을 위한 조치가 없다. TLS를 사용하여 전송된 정보를 암호화하여 전송할 수는 있다.

MQTT 포트

비암호화 : 1883

암호화: 8883

MQTT 브로커

컴퓨터에서 실행되는 소프트웨어 (온프레미스/클라우드)이며, 자체 구축 혹은 제3자가 호스팅할 수 있다.

브로커는 우체국 역할을 한다. MQTT 클라이언트는 의도한 수신자의 직접 연결 주소를 사용치 않고 토픽 이라는 subject line을 사용한다. 구독하는 사람은 누구나 해당 주제에 대한 모든 메시지의 사본 을 받는다.

각 클라이언트는 게시 및 구독을 통해 데이터를 생성 및 수신할 수 있다. 즉, 디바이스는 센서 데이터를 게시하면서도 구성 정보나 제어 명령을 수신할 수 있다. (MQTT는 양방향 통신 프로토콜.) 이는 데이터 공유, 디바이스 관리 및 제어에 도움이 된다. 클라이언트는 동일한 데이터를 다양한 토픽에 브로드캐스트할 수 없으며, 각각 단일 토픽이 지정된 여러 메시지를 브로커에 게시해야 한다.

MQTT 브로커 아키텍처를 사용하면 클라이언트 장치와 서버 애플리케이션이 분리된다. 이런 방식으로 클라이언트는 서로의 정보를 알지 못한다. MQTT는 구성된 경우 인증서, 사용자 이름 및 암호로 보호된 연결에 TLS 암호화를 사용할 수 있다. 선택적으로 연결에는 클라이언트가 제공하고 서버의 사본과 일치해야 하는 인증서 파일 형태의 인증이 필요할 수 있다.

실패 시, 브로커 SW와 Client는 중복/자동 백업 브로커에 자동을 인계할 수 있다. 백업 브로커는 또한 사이트, 클라우드 또는 이들의 조합에서 여러 서버에 걸쳐 클라이언트의 부하를 공유하도록 설정할 수 있다.

브로커는 Sparkplug와 같은 호환 사양을 위한 표준 MQTT와 MQTT를 모두 지원할 수 있다. 이는 동일한 서버에서 동시에 동일한 보안 수준으로 수행할 수 있다.

MQTT의 주요 장점

  1. 구성된 경우 취약하고 안전하지 않은 Client 연결을 제거한다.
  2. 단일 장치에서 수천 개 장치로 쉽게 확장 가능하다.
  3. 보안 자격 증명 및 인증서를 포함하여 모든 클라이언트 연결 상태를 관리하고 추적한다.
  4. 셀룰러 또는 위성 네트워크로 구성된 경우 보안을 손상시키지 않고 네트워크 부담을 줄인다.

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을 주어 대응할 수 있도록 한다.

MQTT 동작 구조

MQTT_protocol_example_without_QoS.svg.png

토픽

메시지를 발행-구독하는 행위는 채널단위로 일어난다. 이를 MQTT에서는 토픽이라고 부르고, 토픽을 슬래시로 구분되는 계층 구조를 갖는다.

company / firstFloor / SWoffice / temp

위 예시에서 슬래시 전후에 있는 company, firstFloor, SWoffice, temp는 모두 각 토픽 레벨이며, 해당 토픽은 Topic level Seperator라고 불리는 슬래시로 구분된다.

와일드 카드

+

company / firstFloor / + / temp

위 예시에서 슬래시 전후에 있는 office, firstFloor, SWoffice, temp는 모두 각각의 토픽 레벨(Topic Level)이며, 해당 토픽은 Topic Level Separator라고 불리는 슬래시로 구분된다.즉, 위의 토픽은 회사 1층의 SW부서의 온도를 체크할 수 있는 토픽이다.

company / firstFloor / + / temp

위는 메시지를 구독-발행할 때 여러 개의 토픽을 한 번에 지정할 수 있도록 지원하는 와일드 카드의 예시이다.[+] 문자는 One-Level Wild Card로, 단 한 개의 토픽을 임의의 토픽으로 대체할 수 있다.즉, 위의 토픽은 회사 1층에 있는 모든 부서의 온도를 체크할 수 있는 토픽이다.

$

$SYS/

[$] 문자로 시작하는 토픽은 시스템에 의해 사용되는 특수한 토픽이다. 이 토픽들은 [#] 문자로 지정해도 포함되지 않으며, 주로 브로커의 내부 메시지를 위해 사용된다.

주의할 점

최상위 토픽이 [/] 문자로 시작되지 않아야 한다. 물론 이 자체로 오류가 뜨지는 않지만 최상위 토픽이 이름 없는 토픽이 되어버린다. 즉, [ / company / firstFloor / SWoffice / temp ] 이런 식으로 되지 않아야 한다. 이는 PC의 디렉토리와 비슷하게 생각한다면 흔히 할 수 있는 실수이다.

  • 토픽 이름에 공백 문자가 들어가면 안 된다.
  • 토픽 이름은 임베디드 IoT 장치와의 호환성을 위해 ASCII 문자만 사용하도록 한다.
  • [#] 문자를 이용해서 토픽 전체를 구독하지 않도록 해야 한다. 오버헤드가 심할 경우 브로커/클라이언트 프로세스가 중단될 가능성이 높다.

출처:

https://underflow101.tistory.com/22

[공대생의 차고:티스토리]

RabbitMQ