ThingsBoard обещает IoT из коробки — у коробки обнаруживаются стенки
ThingsBoard обещает закрыть весь IoT-стек одним развёртыванием: приём телеметрии с любых устройств, правила обработки данных, дашборды, управление устройствами и алерты. Обещание честное — платформа действительно всё это умеет. Но в документации не говорят прямо: за один Docker-контейнер с настройками по умолчанию вы получите систему, которая захлебнётся на первой же сотне устройств, шлющих телеметрию раз в минуту. ThingsBoard — это не «поставили и работает», это полноценная система с базой под серьёзную нагрузку, брокером сообщений и правильно посчитанными ресурсами под движок правил в реальном времени.
Содержание
- Что на самом деле делает ThingsBoard
- База данных: где реально упирается телеметрия
- Брокер сообщений: зачем он, если есть встроенная очередь
- Rule Engine: где упирается CPU, а не диск
- Сколько ресурсов заложить на практике
- Развёртывание: Docker Compose и что в нём должно быть с самого начала
- Кому это действительно нужно, а кому — нет
Что на самом деле делает ThingsBoard
Три модуля составляют ядро платформы, и от их нагрузки на инфраструктуру зависит всё остальное.
Сбор телеметрии. Устройства подключаются по MQTT, CoAP, HTTP или через собственный протокол ThingsBoard поверх gRPC. Каждое сообщение — это одна или несколько временных меток с набором значений (температура, влажность, уровень заряда, координаты, что угодно). При тысяче устройств с интервалом в минуту это уже более десятка миллионов точек в сутки, и каждая должна лечь в базу с индексом по времени и по устройству, чтобы дашборд потом отрисовался за разумное время.
Rule Engine — движок правил. Это сердце платформы: граф узлов, через который проходит каждое входящее сообщение. Узел может отфильтровать сообщение по условию, трансформировать его через JavaScript-функцию, сохранить в базу, отправить алерт или переслать дальше. Именно rule engine превращает сырую телеметрию в события: «температура выше порога три раза подряд — создать алярм», «устройство не присылало данных 15 минут — пометить как offline». Каждое правило исполняется синхронно относительно потока сообщений, и при росте числа устройств это первое место, где вы упрётесь в CPU, а не в диск.
Дашборды и управление устройствами. Виджеты тянут данные напрямую из базы телеметрии через отдельный API, и на сложных дашбордах с десятками виджетов и диапазоном «за месяц» это уже не точечные SELECT, а агрегирующие запросы по миллионам строк. Плюс к этому — иерархия устройств, ассеты (группировка по объектам: здание → этаж → комната → датчик), профили устройств с шаблонами алармов.
Отдельно есть слой очереди сообщений между этими компонентами — по умолчанию in-memory, но для чего-то серьёзнее демо-стенда нужен внешний брокер. Разберём каждый узел инфраструктуры по порядку.
База данных: где реально упирается телеметрия
ThingsBoard хранит два типа данных раздельно, и это ключевое архитектурное решение, определяющее выбор СУБД.
Метаданные — устройства, ассеты, пользователи, права, шаблоны дашбордов, настройки алармов — идут в реляционную базу, практически всегда PostgreSQL. Нагрузка здесь типична для любого веб-приложения: если вы уже настраивали PostgreSQL на VPS, ничего экзотического не будет.
Телеметрия — временные ряды с показаниями устройств — это другая история. По умолчанию ThingsBoard кладёт её в ту же PostgreSQL, в таблицу ts_kv, партиционированную по времени. На небольшом парке устройств (условно — до пары сотен, шлющих данные раз в минуту-две) это работает без нареканий: обычная таблица с составным индексом, обычный VACUUM, обычный бэкап. Но телеметрия растёт линейно и без остановки — это постоянный поток вставок, а не транзакционные данные, которые устаревают и удаляются. Через несколько месяцев непрерывной работы таблица ts_kv на паре тысяч устройств легко разрастается до сотен миллионов строк, и обычная PostgreSQL начинает деградировать и на записи, и на агрегирующих выборках для дашбордов.
Здесь у вас три пути:
- PostgreSQL с расширением TimescaleDB. ThingsBoard поддерживает этот режим из коробки — при установке достаточно выбрать вариант «PostgreSQL + Timescale». Timescale превращает
ts_kvв гипертаблицу с автоматическим партиционированием по времени (chunks), что заметно ускоряет и вставку, и запросы по диапазону дат — именно то, что нужно дашбордам. Это практичный выбор для среднего парка устройств: вы остаётесь в экосистеме PostgreSQL (те же бэкапы, тот же SQL для отладки), но получаете производительность временных рядов — та же идея, что в сравнении TimescaleDB и InfluxDB, только здесь Timescale встроена как штатный режим платформы.
- Cassandra (отдельно или в гибриде с PostgreSQL для метаданных). Для по-настоящему больших объёмов — десятки тысяч устройств, высокая частота отправки — ThingsBoard поддерживает Cassandra как хранилище телеметрии: она спроектирована под write-heavy нагрузку и горизонтальное масштабирование. Плата — отдельный кластер, который нужно администрировать: без опыта эксплуатации Cassandra это создаёт больше проблем, чем решает.
Для подавляющего большинства проектов правильный ответ — PostgreSQL + TimescaleDB. Он не требует отдельного кластера, покрывает диапазон от сотен до нескольких тысяч устройств и остаётся управляемым одним администратором. Переходить на Cassandra стоит только когда вы уже упёрлись в лимиты Timescale на конкретных метриках — не заранее «на всякий случай».
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать VPS под ThingsBoardБрокер сообщений: зачем он, если есть встроенная очередь
У ThingsBoard есть внутренняя in-memory очередь для передачи сообщений между микросервисами платформы (транспортный слой → core → rule engine). Она работает «из коробки», и для одного инстанса на небольшой нагрузке этого достаточно — это то, что вы получите, поднимая ThingsBoard одной командой docker run по официальному quick-start.
Проблема в том, что in-memory очередь живёт и умирает вместе с процессом. Если контейнер перезапускается (обновление, авария, docker-compose restart), все сообщения в очереди на обработку теряются. Для демо-стенда это не страшно. Для продакшна, где потеря телеметрии равна потере данных с реальных устройств, это неприемлемо.
Поэтому в production-конфигурации ThingsBoard используется внешний брокер:
- Kafka — официально рекомендуемый вариант, и самый требовательный по ресурсам. Даёт персистентность сообщений, replay при сбоях, масштабирование партициями. Если вы уже разворачивали Kafka на VPS, то представляете порядок цифр: даже минимальный одноброкерный кластер — отдельный процесс с собственными требованиями к памяти и диску, которые закладываются отдельно от расчёта под платформу.
- RabbitMQ — легче в администрировании и ресурсоёмкости, но менее гибок при масштабировании и не даёт такого же replay, как Kafka.
- AWS SQS / Google Pub/Sub — управляемые опции для облака соответствующего провайдера; на своём VPS не применимы напрямую.
Практический вывод: для пары десятков устройств «на попробовать» встроенной очереди достаточно, не усложняйте. Как только речь заходит о продакшне с деньгами или безопасностью на кону — закладывайте Kafka сразу, потому что миграция очереди на уже работающей системе с накопленными данными — отдельная и не самая приятная задача.
Rule Engine: где упирается CPU, а не диск
Это тот компонент, о котором чаще всего забывают при планировании ресурсов, — интуитивно кажется, что раз данные «просто проходят через систему», нагрузка должна быть небольшой. На практике каждое сообщение телеметрии проходит через граф правил синхронно, и если в цепочке есть JavaScript-трансформация (стандартный узел для нормализации данных — привести единицы измерения, посчитать производную метрику, отфильтровать выбросы), выполняется он в embedded JS-движке на JVM — ощутимо дороже по CPU, чем просто INSERT в базу. Это умножается на количество активных правил и на частоту сообщений: несколько тысяч устройств с интервалом отправки в десятки секунд легко дают десятки сообщений в секунду и заметные пики, когда устройства просыпаются синхронно по одному расписанию — нагрузка на движок правил, отдельная от нагрузки на базу.
Что с этим делать на практике:
- Держите правила простыми там, где можно. Фильтрацию по типу сообщения делайте на уровне профиля устройства, а не внутри JS-скрипта — это дешевле.
- Разносите тяжёлую логику. Если правило должно дёрнуть внешний API или выполнить сложные вычисления — используйте асинхронные узлы (
rest-api-call, очередь) вместо синхронной обработки в основном потоке. - Мониторьте очередь rule engine отдельно. ThingsBoard экспортирует метрики через встроенный endpoint — важно видеть именно глубину очереди правил, а не только CPU и память процесса, потому что рост очереди сообщений сигнализирует, что rule engine не успевает за потоком, задолго до того как это станет заметно на дашбордах.
Микросервисная архитектура ThingsBoard (core, transport и rule engine можно развернуть как отдельные сервисы) существует именно для того, чтобы масштабировать rule engine независимо от остальной платформы. Для одного VPS это избыточно — проще выделить больше CPU монолитному инстансу. Разносить компоненты имеет смысл, когда видно, что узкое место — конкретно rule engine, а не база или сеть.
Сколько ресурсов заложить на практике
Точных цифр «под ключ» никто не даст — сильно зависит от частоты телеметрии, сложности правил и глубины истории на дашбордах. Порядок величин как ориентир, который нужно скорректировать под свою нагрузку:
| Сценарий | Устройства | Телеметрия | БД | Брокер | Примерный VPS |
|---|---|---|---|---|---|
| Пилот / лаборатория | до 50 | раз в 1-5 мин | PostgreSQL | встроенная очередь | 2 vCPU, 4 ГБ RAM |
| Малый продакшн | 100-500 | раз в минуту | PostgreSQL + TimescaleDB | встроенная очередь или RabbitMQ | 4 vCPU, 8 ГБ RAM |
| Средний продакшн | 500-3000 | раз в 30-60 сек | PostgreSQL + TimescaleDB | Kafka (отдельный узел или процесс) | 8 vCPU, 16 ГБ RAM + отдельный узел под Kafka |
| Крупный парк | 3000+ | высокая частота | Cassandra или гибрид | Kafka-кластер | несколько узлов, распределённая архитектура |
Это ориентировочная таблица, а не расчёт под вашу нагрузку — конкретные цифры будут отличаться в зависимости от того, сколько метрик передаёт каждое устройство за одно сообщение и сколько виджетов строят агрегаты по длинным диапазонам. Отдельно стоит вопрос про JVM: ThingsBoard написан на Java, и по умолчанию heap настроен консервативно — на реальной нагрузке его нужно поднимать явным образом через JAVA_OPTS, иначе получите GC-паузы на пиках, которые выглядят как случайные подвисания дашборда. Принцип простой: JVM heap плюс база плюс брокер плюс нужды ОС не должны конкурировать за одни и те же 4 ГБ — память нужно закладывать с запасом, а не впритык.
Развёртывание: Docker Compose и что в нём должно быть с самого начала
Официальный образ thingsboard/tb-postgres — хороший старт, но docker-compose из quick-start документации рассчитан на демо, а не на продакшн. Минимальный рабочий compose-файл для варианта PostgreSQL + TimescaleDB:
services:
thingsboard:
image: thingsboard/tb-postgres:latest
restart: unless-stopped
ports:
- "8080:9090"
- "1883:1883"
- "7070:7070"
- "5683-5688:5683-5688/udp"
environment:
TB_QUEUE_TYPE: kafka
TB_KAFKA_SERVERS: kafka:9092
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/thingsboard
SPRING_DATASOURCE_PASSWORD: ${TB_DB_PASSWORD}
JAVA_OPTS: "-Xms2g -Xmx4g"
volumes:
- tb-data:/data
depends_on: [postgres, kafka]
postgres:
image: timescale/timescaledb:latest-pg15
restart: unless-stopped
environment:
POSTGRES_DB: thingsboard
POSTGRES_PASSWORD: ${TB_DB_PASSWORD}
volumes:
- pg-data:/var/lib/postgresql/data
kafka:
image: bitnami/kafka:latest
restart: unless-stopped
environment:
KAFKA_CFG_PROCESS_ROLES: broker,controller
KAFKA_CFG_NODE_ID: 1
volumes:
- kafka-data:/bitnami/kafka
volumes:
tb-data:
pg-data:
kafka-data:
Три момента, которых часто не хватает в примерах из интернета: пароль вынесен в переменную окружения, а не зашит текстом в YAML; явно заданы JAVA_OPTS с реальным heap; и TB_QUEUE_TYPE: kafka вместо встроенной очереди с самого начала — переключать тип очереди на живой системе с накопленными сообщениями заметно неприятнее, чем сразу выбрать правильный вариант. Порты: 1883 — MQTT, 5683-5688/udp — CoAP, 7070 — gRPC-транспорт, 8080 — веб-интерфейс и REST API. Если устройства ходят через интернет напрямую на сервер, MQTT и CoAP нужно защищать отдельно — TLS для MQTT обязателен вне лабораторных условий, иначе телеметрия и команды идут открытым текстом.
Кому это действительно нужно, а кому — нет
ThingsBoard оправдан, когда у вас разнородный парк устройств — не один тип сенсора, а смесь: температурные датчики, счётчики, GPS-модули, промышленные контроллеры по Modbus через шлюз — и нужна единая точка для правил, дашбордов и алармов поверх всего этого разнообразия. Также он оправдан, когда бизнес-логика завязана на правилах обработки в реальном времени: не «показать график», а «температура в холодильной камере выше порога дольше 10 минут — отправить SMS и создать инцидент».
Если у вас узкая задача под один тип устройств, специализированное решение почти всегда экономичнее по ресурсам и проще в администрировании. Например, для GPS-трекеров транспорта — координаты, треки, геозоны, отчёты по пробегу — есть предметно заточенные системы вроде Traccar, которые не тащат за собой универсальный rule engine и произвольную схему телеметрии: изначально спроектированы под один протокол данных и один сценарий использования. Разница принципиальная: ThingsBoard — универсальная платформа для произвольных датчиков с гибким конструктором правил, специализированная система — оптимизированное решение под конкретный класс устройств с меньшими требованиями к железу и администрированию. Если у вас именно транспортный мониторинг, история с собственным сервером GPS-мониторинга для транспортной компании показывает, во что это выливается на практике без универсальной IoT-платформы поверх.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать VPS под ThingsBoardНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Можно ли начать с встроенной in-memory очереди и позже перейти на Kafka без потери данных?
Технически да — переключение TB_QUEUE_TYPE не требует переустановки платформы, но накопленные в старой очереди неподтверждённые сообщения не переносятся автоматически. Если потеря телеметрии за короткое окно переключения для вас некритична, можно мигрировать позже. Если критично — закладывайте Kafka сразу.
Обязательно ли использовать TimescaleDB, или подойдёт чистый PostgreSQL?
Чистый PostgreSQL подойдёт для небольшого парка устройств и невысокой частоты телеметрии. Проблемы начинаются, когда таблица ts_kv разрастается до десятков-сотен миллионов строк: без партиционирования по времени и запросы на дашборды, и вставка новых точек заметно замедляются. TimescaleDB решает это встроенным партиционированием без смены СУБД.
Сколько устройств потянет один VPS без кластеризации?
Однозначного числа нет — зависит от частоты телеметрии и сложности правил, но диапазон в несколько тысяч устройств с телеметрией раз в минуту на хорошо настроенном сервере (8-16 ГБ RAM, несколько vCPU) обычно достижим без разнесения компонентов на отдельные узлы. Точную цифру для своего случая вы получите только нагрузочным тестированием.
Что произойдёт, если не настроить TLS для MQTT?
Телеметрия и команды устройствам пойдут открытым текстом, включая пароли устройств для аутентификации в брокере. Для лабораторного стенда в изолированной сети это допустимо, для устройств, обращающихся к серверу через интернет, — нет.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →