Рубріки: Теория

Что такое MQTT и для чего он нужен

Андрій Денисенко

Что такое MQTT?

MQTT (MQ Telemetry Transport) — это легковесный протокол обмена сообщениями, работающий по модели «издатель—подписчик». Он предназначен для телеметрии между машинами (M2M) в средах с низкой пропускной способностью. Это самый распространенный протокол передачи сообщений для Интернета вещей (IoT).

MQTT представляет собой набор правил, который определяет, как устройства IoT публикуют данные и подписываются на них через Интернет. Этот протокол используется для обмена сообщениями и данными для IoT и промышленного IoT (IIoT), например встроенными устройствами, датчиками, промышленными программируемыми логическими контроллерами и другими устройствами.

Отправитель (издатель) и получатель (подписчик) связываются с использованием тем (топиков) и разделены между собой. Связью между ними управляет брокер MQTT. Брокер MQTT фильтрует все входящие сообщения и распределяет их между соответствующими подписчиками.

История MQTT

Протокол MQTT создан Энди Стэнфордом-Кларком (IBM) и Арленом Ниппером (Cirrus Link) в 1999 году для подключения систем телеметрии нефтяного трубопровода через спутник. Этот протокол должен был отличаться минимальным потреблением заряда аккумулятора и минимальной полосой пропускания. Изобретатели сформулировали следующие требования к протоколу:

  • простота реализации;
  • доставка данных о качестве обслуживания;
  • легковесность и эффективное использование полосы пропускания;
  • нейтральность по отношению к данным;
  • поддержание постоянства сеансов.

Эти цели до сих пор лежат в основе MQTT. Однако основной фокус протокола сместился с проприетарных встроенных систем на открытые примеры внедрения для Интернета вещей (IoT). MQTT больше не считается аббревиатурой. Теперь MQTT — это название протокола.

Несмотря на то, что MQTT изначально был закрытым, в 2010 году версия 3.1 вышла по лицензии royalty-free. В 2014 году MQTT стал официально утвержденным стандартом OASIS.

Существует два варианта и несколько версий MQTT:

  • MQTT v3.1.0
  • MQTT v3.1.1
  • MQTT v5
  • MQTT-SN

Сейчас широко используется версия 3.1.1. Новейшая версия (5-я) утверждена в 2019 году имеет ограниченную поддержку. Клиент mosquitto поддерживает ее с выпуска 1.6, а клиент Paho (Python) — с версии 1.5.1. Спецификация MQTT-SN появилась в 2013 году. Она предназначена для работы с UDP, ZigBee и другими транспортами.

Особенности MQTT

Ниже перечислены основные особенности MQTT.

  1. Легковесный и эффективный для минимизации ресурсов, требуемых для клиента, и пропускной способности сети.
  2. Обеспечивает двунаправленное взаимодействие между устройствами и серверами. Также обеспечивает передачу сообщений группам вещей.
  3. Масштабируется до миллионов вещей.
  4. Определяет уровни качества обслуживания (QoS) для обеспечения надежности сообщений.
  5. Поддерживает постоянные сеансы связи между устройством и сервером, что сокращает время на повторное подключение по ненадежным сетям.
  6. Сообщения могут шифроваться с использованием TLS и поддерживают протоколы аутентификации клиентов.

В отличие от парадигмы «запрос-ответ» протокола HTTP, протоколом MQTT управляют события и он позволяет отправлять клиентам push-сообщения. Такая архитектура отделяет клиенты друг от друга, позволяя создать решение с высокой масштабируемостью без зависимостей между устройствами, генерирующими данные, и устройствами, принимающими их.

Как работает MQTT

Подключение MQTT всегда устанавливается между клиентом и брокером. MQTT отделяет издателя от подписчика, и клиенты никогда не подключаются друг к другу напрямую. Подключения клиентов всегда обслуживаются брокерами. Для подключения клиент отправляет брокеру сообщение CONNECT. Брокер отвечает сообщением CONNACK с кодом состояния. После установки подключения брокер оставляет его открытым, пока клиент не отправит сообщение об отключении или подключение не будет разорвано.

Рассмотрим клиенты и брокеры подробнее.

Клиенты

Клиентами MQTT являются как издатели, так и подписчики. Они называются издателями и подписчиками в зависимости от того, что делает клиент в определенный момент: публикует сообщения или подписан на их получение. В одном и том же клиенте MQTT может быть реализована функциональность издателя и подписчика. Клиентом MQTT является любое устройство, от микроконтроллера до полнофункционального сервера, на котором выполняется библиотека MQTT и которое подключается к брокеру MQTT по сети. Например, клиентом MQTT может быть очень маленькое устройство с ограниченными ресурсами и минимальной библиотекой, подключенное по беспроводной сети. Также клиентом MQTT может быть типичный компьютер, на котором используется графический клиент MQTT для тестирования. Реализация протокола MQTT для клиента очень проста, поэтому он идеально подходит для маленьких устройств. Клиентские библиотеки MQTT доступны для множества языков программирования, в том числе следующих:

  • Android
  • Arduino
  • C
  • C++
  • C#
  • Go
  • iOS
  • Java
  • JavaScript
  • .NET

Брокеры

Брокер находится в центре любого протокола, работающего по модели «издатель—подписчик». Некоторые реализации брокеров позволяют им обслуживать миллионы одновременно подключенных клиентов MQTT.

Брокер отвечает за получение всех сообщений, их фильтрацию, определение подписчиков для каждого сообщения и его отправку соответствующим клиентам. Также он хранит данные для всех клиентов с постоянными сеансами, в том числе подписки и пропущенные сообщения. Кроме того, брокер выполняет аутентификацию и авторизацию клиентов. Обычно брокер является расширяемым, что упрощает пользовательскую аутентификацию, авторизацию и интеграцию в серверные системы. Интеграция особо важна, потому что брокер часто является тем компонентом, который напрямую связан с Интернетом, обслуживает множество клиентов и должен отправлять срообщения анализироующим и обрабатывающим системам. Поскольку через брокер проходят все сообщения, он должен быть масштабируемым, интегрируемым в серверные системы, простым в отслеживании и устойчивым к сбоям.

Семантика тем

В MQTT слово «тема» означает строку в кодировке UTF-8, которую брокер использует для фильтрации сообщений для каждого подключенного клиента. Тема включает в себя один или несколько уровней. Уровни отделяются друг от друга косой чертой (разделитель уровней темы):

По сравнению с очередью сообщений темы MQTT очень легковесны. Клиенту не нужно создавать требуемую тему перед публикацией или подпиской. Брокер принимает тему без какой-либо предварительной инициализации.

Каждая тема должна содержать по крайней мере один символ. В строке темы допускаются пробелы. Темы чувствительны к регистру. Например, office/temperature и Office/Temperature — это две разных темы. Даже символ косой черты является допустимой темой.

Подстановочные символы MQTT

Когда клиент подписывается на тему, он может подписаться на конкретную тему опубликованного сообщения или использовать подстановочные символы для подписки на несколько тем одновременно. Подстановочный символ может использоваться только для подписки на темы и не может использоваться для публикации. Существует два подстановочных символа: одноуровневый и многоуровневый.

Одноуровневый: +

Одноуровневый подстановочный символ заменяет один уровень темы. Для этого используется символ плюса (+).

Тема соответствует теме с подстановочным символом, если содержит произвольную строку на месте этого символа. Например, подписка на тему office/+/humidity может дать следующие результаты:

+ office/room1/humidity
+ office/conference-room/humidity

Но она не будет соответствовать указанным ниже результатам:

home/room1/humidity
– office/room1/temperature

Многоуровневый: #

Многоуровневый подстановочный символ охватывает несколько уровней темы. Для этого используется символ диеза (#). Чтобы брокер мог определить, какие темы сопоставлять, этот подстановочный символ должен быть последним в теме, а перед ним должна быть косая черта.

 Эта запись будет совпадать со следующими темами:

+ office/room1/humidity
+ office/room1/temperature

Ей не будут соответствовать такие темы:

home/room1/temperature
– office/conference-room/humidity

Когда клиент подписывается на тему с многоуровневым подстановочным символом, он получает все сообщения темы, начинающиеся с шаблона передж подстановочны символом, независимо от количества уровней в теме. Если в качестве темы указан только этот подстановочный символ (#), то будут получены все сообщения, отправляемые брокером MQTT. Если вы ожидаете высокой пропускной способности, подписываться с указанием только многоуровневого подстановочного символа не рекомендуется.

Темы, начинающиеся с символа $

В принципе, вы можете называть темы MQTT, как захотите. Однако есть исключение. Темы, начинающиеся с символа $, имеют другое предназначение. Они не включатся в подписку с использованием многоуровневого подстановочного символа (#). Эти темы зарезервированы для внутренней статистики брокера MQTT. Клиенты не могут публиковать сообщения в этих темах. На данный момент официального стандарта для таких тем нет.

Структура сообщений

MQTT — это двоичный протокол, в котором управляющие элементы представлены двоичными байтами, а не строками текста. MQTT использует формат команды и подтверждения команды. То есть, с каждой командой связано соответствующиее подтверждение.

Названия тем, идентификаторы клиентов, имена пользователей и пароли представлены в виде строк в кодировке UTF-8. Полезная нагрузка за исключением информации протокола MQTT, то есть идентификатора клиента и т. п., представлена в виде двоичных данных, а содержимое специфично для приложения.

Пакет MQTT состоит из двухбайтового фиксированного заголовка (присутствует всегда), переменного заголовка (присутствует не всегдя) и полезной нагрузки (присутствует не всегда).

Возможные форматы пакета таковы:

  • Фиксированный заголовок (управляющее поле + длина). Пример: CONNACK.
  • Фиксированный заголовок (управляющее поле + длина) + заголовок переменной длины. Пример: PUBACK.
  • Фиксированный заголовок (управляющее поле + длина) + заголовок переменной длины + полезная нагрузка. Пример: CONNECT.

Поле фиксированного заголовка состоит из управляющего поля и поля длины пакета (поле переменной длины).

Минимальный размер поля длины пакета составляет 1 байт и подходит для сообщений общей длиной менее 127 байт (не включая поля управления и длины). Максимальный размер пакета — 256 МБ. Пакеты длиннее 127 и короче 16383 байт будут иметь размер поля длины 2 байта и так далее. Примечание. Используется 7 бит, а 8-й является битом продолжения.

Минимальный размер пакета — 2 байта: однобайтовое управляющее поле и однобайтовое поле длины пакета. Например, сообщение DISCONNECT состоит всего из двух байтов.

Управляющее поле

8-битовое управляющее поле — это первый байт двухбайтового фиксированного заголовка. Оно разделено на два 4-битовых поля и содержит все команды и ответы протокола.

Первые 4 наиболее значимых бита являются полем команды или типа сообщения, а вторые используются как управляющие флаги. Например, команда CONNECT имеет двоичный код 0001 (десятичный = 1), CONNACK — 0010 (2), PUBLISH — 0100 (3), DISCONNECT — 1110 (14). Поскольку это старшие биты, фактические коды будут отсчитываться от пятого до восьмого бита, например CONNECT — 00010000 (16), CONNACK — 00100000 (32) и так далее.

Управляющие флаги

Хотя четырьмя битами можно представить 16 управляющих флагов, лишь некоторые используются часто. Сообщение PUBLISH использует все биты, как показано ниже:

Бит 3 Бит 2 Бит 1 Бит 0
DUP QoS QoS RETAIN

Флаг DUP используется при повторной публикации сообщения с QoS 1 или 2.
Флаги QoS используются при публикации с указанием уровня QoS (0 — один раз, не гарантированно, 1 — как минимум один раз, гарантированно, 2 — только один раз, гарантированно).
Флаг RETAIN также используется при публикации.

Остальные байты поля длины

Каждый из байтов поля длины использует 7 битов для указания длины, а MSB используется как флаг продолжения.

Заголовок переменной длины

Как отмечено выше, этот заголовок не всегда присутствует в сообщении MQTT. Он необходим в некоторых типах сообщений MQTT для передачи дополнительной управляющей информации. Этот заголовок похож, но не одинаков для разных типов сообщений.

Полезная нагрузка

В конце концов, пакет может содержать полезную нагрузку. Она является необязательным полем и содержит разную информацию для разных типов пакетов. Обычно это поле содержит отправляемые данные. Например, для пакета CONNECT рабочей нагрузкой является идентификатор клиента, а также имя пользователя и пароль, если они есть. Для пакета PUBLISH это публикумое сообщение.

Пример пакета CONNECT

Первым байтом пакета CONNECT будет 00010000. Команда CONNECT имеет код 1, поэтому старшая четверка битов будет иметь значение 0001, а поскольку флаги отсутствуют, младшие 4 бита будут нулевыми.

Вторым байтом будет длина остальной части пакета. Она складывается из длины заголовка переменной длины и длины полезной нагрузки. Ниже приведен формат заголовка переменной длины и полезной нагрузки пакета CONNECT.

Защита передачи данных

Когда речь идет о безопасности сети IoT, необходимо принять во внимание три базовых концепции: идентификатор пользователя, аутентификацию и авторизацию.

В каждом сценарии MQTT участвуют клиент и брокер. Как уже говорилось ранее, клиентом может быть устройство от микроконтроллера до сервера. Любое устройство, которое подключается к брокеру, считается клиентом.

Брокер получает все сообщения и координирует их публикацию для подписанных клиентов. Брокер несет ответственность за поддержание постоянных подключений, а также идентификацию и авторизацию для передачи данных клиентам MQTT. Подключение MQTT устанавливается только между одним клиентом и брокером.

Идентификатор клиента

Для подключения к брокеру клиент должен передать ему идентификатор клиента в сообщении CONNECT. В идеале каждый клиент имеет уникальный идентификатор клиента. Большинство устройств снабжены универсальным уникальным идентификатором (UUID) или MAC-адресом сетевого устройства для подключения клиента.

Получив сообщение CONNECT, брокер устанавливает, имеет ли право клиент подключиться к брокеру, проверяя идентификатор, имя пользователя и пароль.

Кроме аутентификации с использованием имени пользователя и пароля протокол MQTT позволяет проводить аутентификацию с использованием сертификата X.509. Для этого методом шифрования следует выбрать TLS (Transport Layer Security) .

Авторизация

Когда клиент подключается к брокеру, он может выполнять два действия: публиковать и подписываться на темы. Темы — это основной ресурс, доступный клиентам, и для безопасности системы они требуют авторизации. Без нее любой клиент смог бы подключиться на любую тему, доступную в брокере.

Самыми распространенными типами авторизации являются контроль доступа на основе ролей (Role Based Access Controls, RBAC) и список контроля доступа (Access Control List, ACL).

При использовании RBAC роль предоставляет уровень абстракции между клиентом и основным ресурсом, то есть, в данном случае темами. С определенными ролями связаны определенные разрешения, что позволяет брокеру авторизовать клиента для публикации или подписки на определенную тему.

ACL связывает определенные клиенты со списаом разрешений. Эти разрешения предоставляют политики, определяющие темы, на которые клиент может подписаться или в которых он может публиковать.

Также возможна авторизация с использованием токенов доступа. Они позволяют ограничить разрешения клиента определенной областью, давая возможность предотвратить несанкционированный доступ для чтения или записи данных, который мог бы оказать нежелательное влияние на другие клиентские устройства, подключенные к вашей инфраструктуре IoT.

Сферы использования MQTT

MQTT используется во многих примерах внедрения и отраслях промышленности. На сайте MQTT приведены следующие примеры внедрения.

Автомобильная промышленность

HiveMQ: Приложение BMW для совместного использования автомобилей полагается на надежность подключения, которую обеспечивает HiveMQ.
EMQ помогает SAIC Volkswagen в создании платформы IoV (Интернет транспортных средств).

Логистика

Надежное подключение IoT обеспечивает мониторинг автономных дронов Matternet в режиме реального времени.

Производство

MQTT используется для мониторинга электростанций турецкой компании Çelikler Holding.

Интеллектуальный дом

Пример внедрения телеметрии IBM: мониторинг и контроль электроэнергии в доме.
Пример внедрения телеметрии IBM: домашний мониторинг пациентов.
Система безопасности для интеллектуального дома eFon Technology доверяет решению MQTT компании Bevywise.

Нефтегазовая промышленность

EMQ помогает внедрять инновации сферы IoT в нефтехимической промышленности.

Потребительская продукция

CASO Design создает устройства для интеллектуальной кухни.

Транспорт

IoT развернут в железнодорожной системе Германии Deutsche Bahn AG.

 

Останні статті

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

Переписки, фото, история браузера: киевский программист зарабатывал на шпионаже

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023