Real-Time Backend

MQTT: протокол для IoT и M2M

8 миллиардов IoT-устройств к 2030 году. Умная розетка, датчик температуры, счётчик электроэнергии - все они должны слать данные в облако. HTTP слишком тяжёл: заголовки в сотни байт, нет pub/sub, нет retain. MQTT делает всё это с 2-байтовым заголовком и работает на микроконтроллере с 8KB RAM.

  • **AWS IoT Core**: managed MQTT broker. 100M+ устройств, миллиарды сообщений в день. Интеграция с Lambda, DynamoDB, Kinesis для IoT pipeline
  • **Tesla**: MQTT для телеметрии автомобилей. Каждый Tesla - MQTT publisher. Данные о батарее, температуре, ошибках → MQTT broker → ML-обработка → OTA обновления
  • **Facebook Messenger**: исторически использовал MQTT для мобильных push-уведомлений. Экономия трафика критична для мобильных устройств - MQTT в 5-10x эффективнее HTTP polling

MQTT: pub/sub для машин на 2 байтах заголовка

1999 год. Энди Стэнфорд-Кларк из IBM проектирует протокол для мониторинга нефтепровода через SCADA-системы в пустыне. Требования: минимальный трафик (спутниковая связь стоит $$$), надёжность на ненадёжном канале, работа на микроконтроллерах с 8KB RAM. Результат - MQTT (MQ Telemetry Transport). Заголовок фиксированной части - 2 байта.

Архитектура: publish-subscribe через брокер. Клиент не знает о других клиентах - только о топиках. Устройство (publisher) отправляет данные температуры в топик `sensors/room42/temperature`. Dashboard (subscriber) подписан на `sensors/+/temperature` (wildcard `+` = один уровень). Брокер (Mosquitto, EMQX, HiveMQ) маршрутизирует сообщения.

ML-параллель: MQTT топики - как очереди в streaming pipeline. `sensors/+/temperature` - это filter transform на входе. Wildcard `#` (multi-level) = подписка на все события - аналог catch-all consumer. EMQX обрабатывает 100M+ MQTT-сообщений в секунду - это не 'IoT игрушка', это production-grade messaging для real-time ML inference pipelines.

Чем pub/sub архитектура MQTT принципиально отличается от request-response WebSocket?

QoS уровни: at-most-once, at-least-once, exactly-once

MQTT определяет три уровня гарантии доставки. QoS 0 (at-most-once): fire-and-forget, без подтверждения. QoS 1 (at-least-once): PUBLISH → PUBACK; если PUBACK не пришёл - повтор. Дублирование возможно. QoS 2 (exactly-once): 4-этапный handshake (PUBLISH → PUBREC → PUBREL → PUBCOMP). Гарантировано без дублей, но дороже.

Практика: QoS 0 - телеметрия (потеря одного показания температуры некритична). QoS 1 - уведомления, команды управления (нужна доставка, дубль обработается idempotent образом). QoS 2 - финансовые транзакции, критические команды (отключение питания). Правило: QoS между publisher и брокером + QoS между брокером и subscriber - разные! Итоговый QoS = min(publisher_qos, subscriber_qos).

Устройство публикует с QoS 2, subscriber подписан с QoS 1. Какой итоговый QoS получит subscriber?

Retained messages: последнее известное состояние

Проблема: устройство публикует температуру каждые 5 минут. Новый подписчик (дашборд перезапустился) подключается и ждёт следующего сообщения - до 5 минут без данных. Решение: retained message. Брокер хранит последнее сообщение с `retain: true` для каждого топика. Новый подписчик получает его мгновенно при подписке.

Retained messages - это не история, а только последнее значение. Для истории нужен time-series store. Типовой паттерн: MQTT retained = 'текущее состояние устройства', TimescaleDB/InfluxDB = история. Home Assistant, OpenHAB, AWS IoT Core используют этот паттерн: retained message как single source of truth о текущем состоянии каждого устройства в системе.

Какую проблему решает retained message в IoT-системе?

Last Will and Testament: обнаружение отключений

TCP позволяет детектировать обрыв соединения - но с задержкой (keepalive timeout). IoT-проблема: устройство потеряло питание или wifi - как остальные узнают? MQTT Last Will and Testament (LWT): при подключении клиент указывает 'завещание' - топик и payload, который брокер отправит при неожиданном отключении.

LWT + retained = паттерн 'birth/death certificate' для IoT. При подключении - publish online=true с retain. LWT - offline=true с retain. В любой момент любой новый subscriber узнаёт актуальный статус каждого устройства. Home Assistant использует этот паттерн для availability топика: `homeassistant/sensor/temperature/availability` со значениями 'online'/'offline'.

MQTT - это WebSocket с publish/subscribe поверх него

MQTT - самостоятельный протокол поверх TCP (порт 1883/8883). Существует также MQTT over WebSocket для браузеров, но это транспортный слой - сам протокол не меняется

MQTT был разработан за 10 лет до WebSocket. Оба работают поверх TCP, но MQTT имеет минимальный overhead (2-байтный фиксированный заголовок, бинарный), специфичные для M2M фичи (QoS, retained, LWT) и поддержку ненадёжных каналов

При каком условии брокер публикует Last Will сообщение?

Связанные темы

MQTT - специализированный протокол для IoT и M2M коммуникации:

  • Pub/Sub паттерн — MQTT - конкретная реализация pub/sub архитектуры на уровне протокола
  • WebTransport — WebTransport - следующее поколение: QUIC-based, для браузеров с UDP-семантикой
  • Сравнение подходов — MQTT vs WebSocket vs SSE: выбор протокола под конкретную задачу

Ключевые идеи

  • **MQTT = pub/sub поверх TCP**: publisher → брокер → subscriber. Decoupling полный: publisher не знает о subscriber'ах.
  • **QoS уровни**: 0 (fire-and-forget), 1 (at-least-once, дубли возможны), 2 (exactly-once, 4 RTT). Итоговый QoS = min(publisher, subscriber).
  • **Retained messages**: брокер хранит последнее сообщение топика. Новый subscriber получает текущее состояние мгновенно.
  • **Last Will**: брокер публикует 'завещание' при аварийном отключении (без DISCONNECT). Паттерн birth/death certificate для устройств.
  • **Минимальный overhead**: 2-байтный заголовок, бинарный протокол. Работает на 8KB RAM микроконтроллерах.

Вопросы для размышления

  • MQTT retained хранит только последнее значение. Как построить систему где нужно и текущее состояние (retained) и история последних 24 часов?
  • QoS 2 гарантирует exactly-once, но требует 4 RTT. Как это влияет на latency при 100мс round-trip через спутниковую связь?
  • Wildcard '#' подписывает на все топики. Какие проблемы это создаёт в production с тысячами устройств и как их решить?

Связанные уроки

  • rt-14 — gRPC Streaming - другой подход к бинарным протоколам для machine-to-machine
  • rt-16 — WebTransport - следующий шаг: QUIC-based протокол для браузеров
  • rt-17 — MQTT реализует pub/sub паттерн на уровне протокола
  • net-03-physical — MQTT оптимизирован для ненадёжных сетей - понимание сетевого стека полезно
  • rt-06 — Сравнение с WebSocket: разные trade-off для IoT vs браузеров
  • net-55-message-queues
MQTT: протокол для IoT и M2M

0

1

Войти