bbqmsg 님의 블로그
[통신] MQTT이란 본문
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의 특징
- 연결지향적 (Connection Oriented)
- 브로커를 통한 통신
- MQTT의 발행-구독 메세징 패턴은 오로지 브로클 통해서만 통신할 수 있으며 개설된 Topix에 메세지를 발행하면 해당 Topic을 구독하는 클라이언트들에게 메세지를 발행할수 있다.
- QoS (Quality of Service)
- 0: 최대 1회 전송. Topic을 통해 메세지를 전송할 뿐 보장은 안한다. (보낸 다음 잊어버림)
- 1: 최소 1회 전송. 구독하는 클라이언트가 메세지를 받았는지 불확실하면 정해진 횟수만큼 재전송한다. 중복의 위험성이 있다.(확인 응답을 거치는 전달)
- 이 필드는 기반이 되는 TCP/IP 데이터 전송의 처리에 영향을 주지 않으며, MQTT 송신자와 수신자 간에만 사용된다.
- 메시지는 글자 수 제한이 없으므로, 긴 메시지나 JSON 포맷 또는 파일도 전송이 가능하다.
- 0에 가까울수록 메시지 처리에 대한 부하가 줄어들고, 메시지 손실의 위험이 높아진다. 반대로 2에 가까울수록 메시지 손실 위험을 줄어들지만 메시지 처리 부하가 급격히 늘어난다.
- 단, 0 ~ 1 정도의 QoS를 사용하며 메시지 손실의 위험은 상위 어플리케이션 차원에서 관리하는 방법이 널리 쓰이고 있다.
- 메세지 유형
- 연결하기
- 서버와의 연결 수립을 기다린 다음 노드 간 링크를 만든다.
- 연결 끊기
- MQTT 클라이언트가 해야 할 일을 기다리고 인터넷 프로토콜 스위트 세션의 연결이 끊어지기를 기다린다.
- 발행하기
- MQTT 클라이언트에 요청이 전달된 직후 어플리케이션 스레드에 즉시 반환한다.
- 각각의 메세지의 event에 따라 MQTT 브로커가 Notification을 주어 대응할 수 있도록 한다.
- 연결하기
- 다양한 개발언어의 다양한 클라이언트 지원
- C/C++/Java/Node.js/Python/Arduino 등
트위터뿐만은 아니지만 트위터는 구독이 메인인 SNS이다. 내가 관심 있는 사람, 기관, 키워드를 구독하면 구독한 모든 곳에서 새롭게 글이 작성될 때마다 내 피드에 하나하나 추가되면서 우리는 그 글들을 확인할 수 있다. 그럼 우리는 구독한 구독자, 우리가 구독한 사람들은 글을 쓴 발행인이 된다.
넷플릭스도 구독이 있다. 그러나 트위터와 다른 점은 오징어 게임이나, 지금 우리 학교는 같은 콘텐츠를 오직 넷플릭스만 발행할 수 있다는 점이다. 우리는 구독해서 보는 것만 가능하다. 그러나 트위터는 내가 구독한 사람들의 글을 피드에 받으며 구독자가 되기도 하지만 내가 직접 글을 올리면 나를 구독한 사람의 피드에 내 글이 올라가며 우리는 발행인의 역할 또한 될 수 있다. 그 두 가지의 역할을 하는 우리는 트위터 사용자인 것이다.
MQTT의 구조는 크게 세 분류로 되어있다. 이것을 위의 twitter에 대입해보면
- Subscriber : 다른 사람, 기관, 키워드를 구독한 사용자
- Publisher : 글을 작성한 사용자
- Broker : twitter 서버
인 것이다. 그래서 전송 과정은 Publisher가 글을 쓰면 Broker로 가서 구독한 Subscriber 전체에게 메시지를 뿌리게 되는 것이다. twitter와의 차이점은 구독한 곳에서 발행된 이전 글들을 모두 볼 수 있지만 MQTT는 내가 접속한 이후부터의 글만 볼 수 있다. 또한 MQTT는 구독한 곳에 메시지가 누적되어 쌓이는 것이 아니라 가장 최근의 메시지만 남아있는 방식이다.
MQTT 안에서는 사람이나 기관, 키워드를 구독하는 것이 아닌 Topic을 구독한다. Topic에 대해서 자세하게 알아보도록 하겠다.
토픽 (Topic)
메세지를 발행-구독하는 행위는 채널 단위로 일어난다. 슬래시(/)로 계층을 구분한다.
company / firstFloor / SWoffice / temp
예로 회사의 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 문자만 사용하도록 한다.
- [#] 문자를 이용해서 토픽 전체를 구독하지 않도록 해야 한다. 오버헤드가 심할 경우 브로커/클라이언트 프로세스가 중단될 가능성이 높다.
MQTT의 장/단점
- tree구조의 topic을 이용해 사용자가 원하는 값만 실시간으로 받아올 수 있음.
- 낮은 대역폭으로 인터넷 환경이 좋지 않아도 다른 통신 방법에 비해 원활히 사용이 가능함.
- 한 명 한명 메시지를 보내는 것이 아니라 중간의 Broker가 자신을 구독한 사용자에게 한 번에 뿌려줌.
이 세 개가 큰 장점이라고 할 수 있다.
단점도 존재한다. 이 단점으로 인해 위에서 언급한 배달의 민족이 MQTT를 활용하지 못했다.
바로, Publisher와 Subscriber 둘 다 온라인 상태일 때만 Subscriber가 메시지를 받을 수 있는 것이다. Subscriber가 오프라인일 때 보류해 두었다가 온라인이 되면 메시지를 쏴 주는 방식이 아니라서 배달의 민족에선 배터리를 위해 사용하지 않으면 자동으로 대기모드로 들어가 버리는 스마트폰의 특성 때문에 MQTT의 접속을 지속시킬 수 없었다.
'통신' 카테고리의 다른 글
디지털 인증서의 원리와 생성 과정 (2) | 2024.10.22 |
---|