Коротко: что это такое
MQTT (Message Queuing Telemetry Transport) — лёгкий протокол обмена сообщениями по модели «публикация — подписка», рассчитанный на устройства со слабым каналом связи, ограниченной памятью и питанием от батареи.
Его придумали в 1999 году Энди Стэнфорд-Кларк (IBM) и Арлен Ниппер (Arcom) для телеметрии нефтепроводов через спутник. Условия были такие: канал дорогой и узкий, связь рвётся, устройства слабые. Из этих ограничений и выросли главные свойства протокола — крошечный служебный заголовок, работа поверх одного долгоживущего соединения и способность пережить обрыв, не потеряв сообщения.
Сегодня MQTT — стандарт OASIS, а версия 3.1.1 принята ещё и как международный стандарт ISO/IEC 20922. Протокол давно вышел за пределы нефтянки: на нём работают умные дома, счётчики, станки, автомобили и медицинские приборы.
Минимальный служебный заголовок сообщения — два байта. Для сравнения, один HTTP-запрос с заголовками — это сотни байт, и это ещё до полезных данных. Когда устройство отправляет показание температуры раз в секунду с симки в поле, разница становится решающей.
Как это работает: публикация, подписка и брокер
В HTTP клиент спрашивает — сервер отвечает. В MQTT никто ни у кого ничего не спрашивает: устройство публикует сообщение в тему, а все, кто на эту тему подписан, его получают. Отправитель не знает, кто его читает и читает ли вообще; получатель не знает, кто прислал. Их связывает только имя темы.
Посередине всегда стоит брокер — сервер, который держит соединения, разбирает подписки и раздаёт сообщения. Без него схема не работает: именно он превращает «отправил в никуда» в «дошло до всех, кому надо».
Что делает брокер
- Принимает и держит соединения — тысячи одновременно, годами без разрыва.
- Проверяет, кто подключается: логин, пароль, сертификат или токен.
- Решает, кому что можно: права на публикацию и подписку задаются по темам.
- Сопоставляет каждое опубликованное сообщение с деревом подписок и рассылает копии.
- Хранит состояние: последние значения (retain), очереди для отключившихся, незавершённые подтверждения.
- Отслеживает, кто жив, и рассылает «последнюю волю» за тех, кто пропал.
Развязка отправителя и получателя — не техническая мелочь, а главное следствие модели. Датчик можно заменить, добавить второго подписчика, поставить рядом систему аналитики — и ничего не переписывать: все они разговаривают с темой, а не друг с другом.
Темы и подстановочные знаки
Тема — это строка с уровнями, разделёнными косой чертой. Никакой предварительной регистрации: публикация в новую тему создаёт её на лету.
office/floor2/room14/temperature
office/floor2/room14/humidity
office/floor2/room15/temperature
Подписка умеет захватывать целые ветки двумя знаками:
| Знак | Что значит | Пример | Что поймает |
|---|---|---|---|
+ | ровно один уровень | office/floor2/+/temperature | температуру во всех комнатах второго этажа |
# | всё, что глубже, включая текущий уровень | office/# | вообще все темы офиса |
Знак # допустим только последним уровнем: office/#/temperature — некорректный фильтр. Темы чувствительны к регистру, а office/floor2 и office/floor2/ — это две разные темы.
$, зарезервированы под служебные — обычно это $SYS со статистикой брокера. Подстановочные знаки до них не достают: подписка на # не покажет $SYS, для этого нужен явный фильтр.Качество обслуживания: QoS 0, 1 и 2
MQTT позволяет выбирать, сколько усилий тратить на доставку каждого сообщения. Уровень задаётся отдельно при публикации и отдельно при подписке; фактический уровень доставки — меньший из двух.
| Уровень | Гарантия | Как работает | Когда уместен |
|---|---|---|---|
| QoS 0 | не более одного раза | отправил и забыл, подтверждений нет | частая телеметрия, где следующее значение всё равно придёт через секунду |
| QoS 1 | не менее одного раза | получатель отвечает PUBACK, при молчании отправка повторяется | события, которые нельзя потерять, но дубль не страшен |
| QoS 2 | ровно один раз | рукопожатие из четырёх пакетов, дубли отсекаются | команды и биллинг, где повтор означает ошибку |
Цена растёт вместе с гарантией: QoS 2 — это четыре пакета вместо одного и хранение состояния на обеих сторонах. Соблазн «поставить везде двойку на всякий случай» стоит побороть: парк из десяти тысяч датчиков, шлющих QoS 2 каждую секунду, нагружает брокер на порядок сильнее без всякой пользы.
Retain, Last Will, сессии и keep-alive
Retain — последнее известное значение
Обычное сообщение достаётся только тем, кто подписан прямо сейчас. Сообщение с флагом retain брокер вдобавок запоминает, и каждый новый подписчик получает его немедленно при подписке. Именно так решается вечная задача «панель открылась и висит пустая, пока датчик не соизволит прислать следующее показание».
В теме хранится ровно одно retain-сообщение — последнее. Чтобы стереть его, публикуют в ту же тему пустое тело с флагом retain.
Last Will — сообщение на случай обрыва
При подключении клиент может передать брокеру «завещание»: тему, текст и параметры. Если связь оборвётся не по-человечески — без пакета DISCONNECT, — брокер сам опубликует это сообщение. Классическое применение: тема device/42/status с retain, куда при подключении пишется online, а в завещании лежит offline. Система всегда знает, кто на связи, без всякого опроса.
Сессии: чистые и постоянные
Чистая сессия живёт ровно столько, сколько соединение: отключился — подписки забыты, начинай сначала. Постоянная переживает разрыв: брокер помнит подписки и копит сообщения QoS 1 и 2, пока клиент отсутствует, а при возвращении отдаёт накопленное. Для устройства, которое просыпается раз в час, это единственный способ ничего не пропустить.
Keep-alive — как заметить, что связь умерла
Оборванное TCP-соединение может «висеть» живым для обеих сторон очень долго. Поэтому клиент объявляет интервал keep-alive и, если сказать нечего, шлёт пинг. Не услышав ничего за полтора интервала, брокер считает клиента пропавшим, закрывает соединение и публикует его последнюю волю.
Версии протокола: 3.1, 3.1.1 и 5.0
Версий, которые реально встречаются, три. Разница между ними — не косметическая.
| Версия | Год | Статус | Что важно знать |
|---|---|---|---|
| MQTT 3.1 | 2010 | устаревшая | спецификация IBM; ограничение client id в 23 символа; в новых проектах не нужна |
| MQTT 3.1.1 | 2014 | стандарт OASIS, ISO/IEC 20922 | самая распространённая версия; поддерживается буквально всем |
| MQTT 5.0 | 2019 | стандарт OASIS | крупная переработка: свойства пакетов, коды причин, общие подписки |
Отдельно стоит MQTT-SN — родственный протокол для сетей, где нет TCP: ZigBee, радиоканалы, UDP. Это не «версия MQTT», а самостоятельная спецификация; в такие сети ставят шлюз, который переводит трафик в обычный MQTT.
Что реально даёт MQTT 5.0
Пятая версия появилась из накопившихся практических неудобств. Самое заметное:
- Коды причин. В 3.1.1 отказ выглядел как молча закрытое соединение — гадай, что не так. В 5.0 сервер отвечает конкретно: не тот пароль, нет прав на тему, превышен размер пакета.
- Свойства пакетов. К сообщению можно приложить метаданные:
Content Type,Correlation Data, произвольные пользовательские пары ключ-значение. Раньше это запихивали в тело или в имя темы. - Запрос-ответ. Поля
Response TopicиCorrelation Dataделают привычный RPC штатным сценарием, а не самодельным костылём. - Общие подписки
$share/группа/фильтр: несколько экземпляров обработчика делят поток между собой. Это балансировка нагрузки и отказоустойчивость на уровне протокола. - Срок жизни сессии и сообщения.
Session ExpiryиMessage Expiryпозволяют сказать «храни сутки, потом забудь» вместо вечного «чисто или не чисто». - Контроль потока.
Receive Maximumограничивает число неподтверждённых сообщений, аMaximum Packet Sizeзащищает слабое устройство от пакета, который оно не переварит. - Псевдонимы тем. Длинное имя передаётся один раз, дальше идёт двухбайтовый номер — заметная экономия для длинных иерархий.
- Идентификаторы подписок, No Local, Retain As Published, Retain Handling. Мелочи, которые убирают вечные грабли: эхо собственных сообщений, лавину retain при переподключении, невозможность понять, по какой подписке пришло сообщение.
- Задержка последней воли.
Will Delay Intervalне поднимает тревогу из-за мигнувшей связи: завещание уходит, только если клиент не вернулся за отведённое время.
Практический вывод: для нового проекта берите 5.0. Общие подписки и внятные коды ошибок экономят недели отладки, а совместимость со старыми устройствами никуда не девается.
MQTT против HTTP и других протоколов
Вопрос «зачем нужен MQTT, если есть REST» задают часто. Разница не в моде, а в направлении и стоимости общения.
| MQTT | HTTP / REST | |
|---|---|---|
| Модель | публикация — подписка, многие ко многим | запрос — ответ, один к одному |
| Кто начинает разговор | любая сторона: сервер может отправить в любой момент | только клиент; сервер молчит, пока его не спросят |
| Соединение | одно, долгоживущее | обычно новое на запрос |
| Служебные данные | от 2 байт | сотни байт заголовков |
| Узнать об изменении | приходит само | опрашивать по таймеру |
| Работа при обрыве | очереди, повторы, retain, завещание | запрос просто не удался |
| Где сильнее | телеметрия, команды, события | документы, файлы, интеграции, веб |
Показательный пример — опрос. Чтобы узнавать о событии в течение секунды по HTTP, тысяча устройств должна опрашивать сервер тысячу раз в секунду, и почти все ответы будут «ничего нового». В MQTT событие приходит само в тот момент, когда произошло, и трафика при этом нет вовсе.
А что с CoAP, AMQP и WebSocket
- CoAP — REST поверх UDP для совсем маломощных узлов. Легче MQTT, но не даёт ни очередей, ни надёжной доставки без ухищрений.
- AMQP — тяжелее и богаче: сложная маршрутизация, транзакции, очереди корпоративного класса. Уместен между серверами, избыточен для датчика.
- WebSocket — это транспорт, а не альтернатива: MQTT сам умеет ходить поверх WebSocket, чтобы работать прямо в браузере.
- Sparkplug B — не конкурент, а надстройка над MQTT: описывает, как именовать темы и кодировать данные в промышленных системах, чтобы SCADA от разных вендоров понимали друг друга.
Транспорт, порты и полезные данные
MQTT работает поверх TCP и требует от него только надёжной упорядоченной доставки. Общепринятые порты:
| Порт | Что это |
|---|---|
1883 | MQTT поверх TCP, без шифрования |
8883 | MQTT поверх TLS — стандартный порт для защищённого соединения |
80 / 443 | MQTT over WebSocket: обычно единственный способ пробиться из браузера и через строгий корпоративный фаервол |
Тело сообщения для протокола — просто последовательность байт. MQTT ничего не знает о его содержимом и ничего не навязывает: там может лежать JSON, CBOR, protobuf, одно число или картинка. Формально предел — 256 МБ, но на практике всё, что больше сотен килобайт, лучше отдавать по HTTP, а в MQTT слать ссылку.
На практике чаще всего используют JSON: его читает человек, разбирает любой язык, и он достаточно компактен. Для узкого канала имеет смысл двоичный формат — и вот тут пригождается свойство Content Type из MQTT 5.0, которое позволяет честно объявить, что именно лежит внутри.
Безопасность
Сам по себе MQTT не шифрует ничего: на порту 1883 логин и пароль идут открытым текстом. Защита собирается из трёх независимых слоёв, и пропускать нельзя ни один.
Шифрование канала
TLS на порту 8883. Для устройств, которые не тянут TLS по производительности, единственный приличный вариант — держать их в изолированной сети, а наружу выпускать только через шлюз.
Аутентификация
Классика — логин и пароль в пакете CONNECT. Строже — клиентские сертификаты: устройство предъявляет свой, брокер проверяет подпись. Гибкий вариант — JWT: устройство приносит подписанный токен с ограниченным сроком, и отзыв доступа не требует правок в брокере. Хорошие брокеры умеют брать учётки из внешней базы, CSV-файла или HTTP-сервиса, чтобы не дублировать список устройств в двух местах.
Права по темам
Аутентификация отвечает на вопрос «кто ты», авторизация — «что тебе можно». Списки доступа (ACL) описывают, какие темы клиенту разрешено читать и в какие писать. Правильная настройка — запрещено всё, кроме явно разрешённого.
# на чтение и запись. Одна украденная прошивка, и злоумышленник видит весь трафик системы и может отдавать команды любому устройству. Замыкайте устройство в его собственную ветку: device/{id}/# и ничего больше.К этому добавляются ограничение частоты публикаций (чтобы взбесившееся устройство не завалило брокер), лимит размера пакета и обычная сетевая гигиена: панель управления брокером не должна смотреть в интернет напрямую.
Где MQTT применяется на практике
Умный дом и автоматизация зданий
Самая массовая область. Home Assistant, Zigbee2MQTT, ESPHome, openHAB — всё это разговаривает через MQTT-брокер. Он же оказывается клеем между оборудованием разных производителей: розетка, датчик протечки и контроллер отопления от трёх разных вендоров прекрасно работают вместе, потому что каждый просто пишет в свою тему.
Промышленность и SCADA
Показания станков, состояние линий, счётчики наработки. Классическая связка — шлюз, который читает Modbus или OPC UA с оборудования и публикует в MQTT, а дальше данные разбирают SCADA, историзатор и система предиктивного обслуживания — одновременно и не мешая друг другу. Именно здесь пригождается Sparkplug B и общие подписки из MQTT 5.0.
Учёт ресурсов и ЖКХ
Счётчики воды, газа, электричества и тепла: устройства на батарейках, которые просыпаются раз в час, отдают показание и засыпают. Постоянные сессии и retain здесь работают на полную: сервер всегда видит последнее значение, даже если счётчик выйдет на связь только к вечеру.
Транспорт и телематика
Координаты, расход топлива, состояние рефрижератора, поведение водителя. Канал — сотовая сеть, которая пропадает в тоннелях и за городом. Очереди и переотправка после переподключения превращают рваную связь в непрерывный поток данных.
Энергетика, сельское хозяйство, медицина
Солнечные станции и подстанции, поливные системы и метеостанции, мониторы состояния пациентов и холодильники с вакцинами. Общее у них одно: много точек, слабый канал, недопустимость потери событий и необходимость мгновенно узнавать об аварии.
Умный город и логистика
Освещение, парковки, мусорные контейнеры с датчиком заполнения, отслеживание грузов и температуры в цепочке поставок. Десятки тысяч устройств, редкие короткие сообщения — ровно тот профиль нагрузки, под который MQTT и создавался.
Как проектировать темы: что стоит сделать сразу
Схема тем — это API вашей системы. Переделывать её потом больно, потому что придётся одновременно обновлять прошивки и серверную часть. Несколько правил, которые экономят время.
- От общего к частному.
завод/цех3/линия2/станок7/температура— по такой иерархии удобно подписываться на любом уровне. Обратный порядок сделает подстановочные знаки бесполезными. - Идентификатор устройства — отдельным уровнем. Это позволит одним правилом ACL замкнуть устройство в его ветке.
- Без ведущей косой черты.
/office/tempсоздаёт пустой первый уровень — формально это законно, но потом путает всех. - Только латиница, цифры, дефис и подчёркивание. Пробелы,
+,#и$в именах — источник неочевидных поломок. - Не кодируйте в теме то, что меняется. Тема
sensor/42/temp/21.5— ошибка: значение принадлежит телу сообщения, иначе брокер получит бесконечное дерево тем и retain станет бесполезен. - Разделяйте состояние и команды. Например,
device/42/state— то, что устройство сообщает о себе, иdevice/42/cmd— то, что ему приказывают. Иначе эхо собственных команд рано или поздно закольцует логику. - Статус — retain, телеметрию — нет. Retain хорош для «последнего известного состояния», но бессмысленен для потока показаний.
v1 в начале темы стоит ровно ничего, а через два года позволит запустить новый формат сообщений, не ломая парк старых устройств.Как выбрать брокер
Брокеров много, и выбор обычно сводится к нескольким вопросам.
- Поддерживает ли он MQTT 5.0 полностью? Частичная поддержка встречается часто, и выясняется это обычно в неподходящий момент.
- Что с наблюдаемостью? Возможность увидеть, кто подключён, какие темы живут и что именно летит прямо сейчас, экономит часы отладки. Брокер без панели превращает любую проблему в чтение логов.
- Как заводятся устройства? Если их тысячи, руками это не делается — нужен API или учётки во внешней базе.
- Переживает ли перезапуск? Retain, постоянные сессии и очереди должны сохраняться на диск, иначе плановая перезагрузка сервера обернётся потерей данных.
- Что с ограничениями? Одно взбесившееся устройство не должно ронять систему: нужны лимиты по частоте и объёму.
- Сколько это стоит и на чём работает? Облачный сервис удобен, пока не начинает считать деньги за сообщения; свой сервер требует администрирования, но данные остаются у вас.
Для небольшой и средней установки — от умного дома до завода на несколько тысяч точек — обычно достаточно одного брокера на скромном сервере. Кластеризация нужна заметно реже, чем кажется на этапе проектирования; чаще выгоднее связать два независимых брокера мостом, пересылающим только нужные темы.
С чего начать за пять минут
Самый быстрый способ разобраться — поднять брокер и посмотреть на сообщения своими глазами. На Debian или Ubuntu это три команды:
sudo wget -qO /usr/share/keyrings/elx-repo.gpg https://repo.um-d.ru/elx-repo.gpg
echo "deb [signed-by=/usr/share/keyrings/elx-repo.gpg] https://repo.um-d.ru stable main" | sudo tee /etc/apt/sources.list.d/elx-repo.list
sudo apt-get update && sudo apt-get install elxmqttbroker
Панель откроется на http://адрес-сервера:8567. Заведите пользователя, а дальше можно проверить обмен любым клиентом — например, консольным mosquitto:
# в одном окне — подписка на всё, что шлёт устройство
mosquitto_sub -h localhost -u sensor-42 -P пароль -t 'sensor-42/#' -v
# в другом — публикация показания
mosquitto_pub -h localhost -u sensor-42 -P пароль -t 'sensor-42/temp' -m '21.5'
# то же самое, но значение запомнится для новых подписчиков
mosquitto_pub -h localhost -u sensor-42 -P пароль -t 'sensor-42/temp' -m '21.5' -r
Дальше стоит поиграть с флагом retain, отключить подписчика и посмотреть, что накопится в постоянной сессии, задать последнюю волю и выдернуть кабель. Полчаса таких экспериментов дают больше понимания, чем любая статья, включая эту.
Короткие ответы
Что такое MQTT простыми словами?
Это способ для устройств обмениваться короткими сообщениями через посредника. Устройство отправляет сообщение в именованную «тему», а все программы, подписанные на эту тему, немедленно его получают. Отправитель и получатель ничего не знают друг о друге, что позволяет менять и добавлять их независимо.
Зачем нужен MQTT-брокер?
Брокер — это сервер, который держит соединения со всеми устройствами, проверяет их права, сопоставляет опубликованные сообщения с подписками и рассылает копии получателям. Без брокера обмен по MQTT невозможен: публикация и подписка встречаются именно в нём.
Чем MQTT 5.0 отличается от 3.1.1?
Главное: понятные коды причин отказа вместо молча закрытого соединения, свойства пакетов с метаданными, штатный сценарий «запрос — ответ», общие подписки для балансировки нагрузки между обработчиками, управляемые сроки жизни сессий и сообщений, контроль потока и псевдонимы тем для экономии трафика.
Нужно ли переходить на MQTT 5.0?
Для новых проектов — да, выгода заметная, а совместимость сохраняется. Существующую систему на 3.1.1 переводить срочно незачем: обе версии работают на одном брокере одновременно, поэтому устройства можно переключать постепенно, по мере обновления прошивок.
Какой QoS выбрать?
QoS 0 — для частой телеметрии, где потеря одного значения не важна. QoS 1 — для событий, которые терять нельзя, если приёмник умеет отбрасывать дубли. QoS 2 — только для команд и биллинга, где повторная обработка недопустима. Ставить QoS 2 везде «на всякий случай» — самый простой способ перегрузить брокер.
Что такое retain в MQTT?
Флаг, по которому брокер запоминает сообщение и отдаёт его каждому новому подписчику сразу при подписке. В теме хранится только последнее такое сообщение. Это стандартное решение задачи «показать текущее состояние сразу, а не ждать следующего обновления датчика». Удаляется публикацией пустого тела с тем же флагом.
Что такое Last Will?
Сообщение, которое клиент передаёт брокеру при подключении, а тот публикует его сам, если связь оборвалась без корректного отключения. Обычно так помечают устройство как offline, чтобы система узнавала о пропаже без опроса.
Безопасен ли MQTT?
Протокол сам по себе не шифрует данные: на порту 1883 пароль идёт открытым текстом. Безопасность обеспечивают TLS на порту 8883, аутентификация по паролю, сертификату или JWT, и списки доступа по темам, работающие по принципу «запрещено всё, кроме явно разрешённого».
Сколько устройств выдержит один брокер?
Это зависит от брокера и нагрузки, но ориентир такой: один процесс на обычном сервере уверенно держит десятки тысяч одновременных соединений при типичной телеметрии. Упирается всё обычно не в число устройств, а в частоту сообщений и требуемый QoS.
MQTT работает в браузере?
Да, через MQTT over WebSocket. Браузер не умеет открывать произвольные TCP-соединения, поэтому протокол заворачивают в WebSocket — и веб-панель может подписываться на темы напрямую, без промежуточного сервера.
Что означают + и # в темах?
Это подстановочные знаки для подписки. Знак + заменяет ровно один уровень темы, знак # — все оставшиеся уровни и допустим только в конце фильтра. Публиковать в тему с подстановочными знаками нельзя, они работают только при подписке.
Чем MQTT лучше HTTP для интернета вещей?
Он не требует опроса: сообщение приходит само в момент события. Служебный заголовок начинается с двух байт вместо сотен, соединение одно и долгоживущее, а очереди, повторы и retain позволяют пережить обрыв связи без потери данных. Для отчётов, файлов и интеграций HTTP по-прежнему удобнее.