• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

MQTT

nikolz

Well-known member
Интересно ядро какое. Может же быть что-то как Raspberry Pi.
MQTT работает поверх UDP, но в этом случае думаю и брокер и клиенты должны быть в одной сети.
Ядро - интел
MQTT в широко применяемых брокерах как правило использует TCP
но есть решения с использованием UDP которые доказали свое превосходство над классикой особенно для встраиваемых систем.
---------------------
Поясню относительно теста.
Посмотрите внимательно на то, что я написал:
Информация к размышлению:
делал тест системы сервер-клиент UDP для "системы умный дом" .
Сервер с одним ядром успевает обрабатывать до 40 тысяч пакетов в секунду.
По UDP можете подключать любое количество, так как нет надобности устанавливать соединение и держать его открытым.
Трафик минимум в два раза меньше.

Обратите внимание - я не написал что это wifi
я не написал что это ESP
Тест решал задачу проверки пропускной способности виртуального малобюджетного сервера
это сервер для создания системы умного дома с выходом в интернет и затратами на его содержание в пределах 10 долларов в год.
а также возможность защиты от DDOS- атак.
В итоге мне удалось сделать такой сервер с указанной пропускной способностью.
-------------------
На форуме есть такой пердун -pvvx
так как он тридцать лет ковыряется в чипах,
то считает себя всезнающим в любых вопросах и всевидящим в мировом масштабе.
-------------------

Поэтому он лезет как глист во все дырки со своими нравоучениями
На форуме он как петух в курятнике.
Если не затопчет очередного дуринщика, то чувствует себя плохо.
----------------------
Рекомендую фильтровать его высказывания,
так как все, что не касается его измерений тока или напряжения ,
обычно является его самохвальством и словесным поносом.
 

pvvx

Активный участник сообщества
Ядро - интел
MQTT в широко применяемых брокерах как правило использует TCP
но есть решения с использованием UDP которые доказали свое превосходство над классикой особенно для встраиваемых систем.
И как всегда от дебила nikolz примера так и не дождались. Одни отговорки :p
 

pvvx

Активный участник сообщества
В очередной раз nikolz залез в тему, в которой у него нет знаний, и навязывает своё непроверенное решение. Даже не решение, а фантазию. И далее, тут-же в этом признается, попутав персонажей и всю детерминацию, с переносом обвинений в своих поступках на других :)

Разжеванно, для nikolz, т.к. он не читал сообщений этой темы, а просто влепил свою рекламу:

Вопрос о ‘как передавать поток с множества датчиков’ в стандартный сетях ныне очень актуальный, но красивых рабочих решений в открытом доступе по нему нет. Структура IoT связей ещё строится и стандартов, как и отработанных типовых решений нет.

В данной теме (про датчики 9-ти осей), для оптимизации, требуется одно соединение за весь цикл передачи потока координат с датчиков, да с привязкой по времени. Привязка по времени может быть не явная, а представлена как последовательность замеров с определенным дискретным шагом. UDP пакеты не гарантируют последовательность приема и в текущих сетях ограничены 500 байт, что может быть мало или будет мало когда вставите в раздельные пакеты UDP свои метки синхронизации и допишите на стороне клиента и сервера сборку правильной последовательности потока с контролем выпадений.
Когда перепишите всё что имеет и отлажено человечеством в TCP на транспорт в UDP – получите TCP over UDP (с) Nikolz :)
 

pvvx

Активный участник сообщества
И о потреблении, при 20 замерах всех значений в секунду с GY-91 (MPU9250 + BMP280) на модуле JDY-10 (TLSR8266) c UBIA
Общее:
1585479449867.png
Модуля GY-91:
1585479464585.png
 

pvvx

Активный участник сообщества
Не понятно для чего на каждый запрос запускать сторонний процесс для CGI, почему не использовать FastCGI, а сознательно грузить систему каждый раз поднимая новый процесс.
Если нет нужды запускать внешние процессы, а только обрабатывать на сервере запросы клиентов, совершенно не обязательно на каждый запрос на соединение строить новый поток.
На старте сервера строим несколько потоков, которые должны обрабатывать запросы клиентов, все эти потоки прослушивают один и тот-же порт, запросы клиентов начинают обрабатываться в незанятых потоках.
Если все потоки заняты, очередной клиент подключившись (если позволяет очередь backlog) ожидает обработки запроса когда освободится какой-либо поток.
До CGI мы ещё доберемся, но ему предшествует простое HTTP соединение. Вот с него и начнем.

Простейший тест HTTP запросов к web на OpenWRT, модуль NanoPi-R1.
Установлена версия: LuCI openwrt-18.06 branch (git-18.228.31946-f64b152) / OpenWrt 18.06.1
Установлена поддержка HTTPS, web по HTTP отдает только ответ переадресации на HTTPS. Этот ответ web и измерим в apache-jmeter-3.1.
Возьмем 10 потоков (пользователей), т.к. более у httpd уже будет не хватать возможностей (будут ошибки соединений).
Тест связи по WiFi:
1585482154735.png
Видим, что некоторые транзакции (запрос-ответ) уже имеют время исполнения 3049 ms (3 секунды), а вы говорите о каких-то мелочах в CGI.
Расшифровка: Average, Min, Max - это время от запроса до ответа в ms. Остальное нас пока не интересует.
Что там происходило:
1585482359141.png
Т.е. при средней загрузке наблюдаем задержку в 1 сек.

Тест связи по WAN (провод в 1GB сеть):
1585482399495.png
В общем всё то-же самое, но выпала большая задержка.

Мелочи не важны, но имеем среднее время на запрос-ответ без всякой обработки в 365 ms, интерфейс связи при этом без разницы.
В среднем 1500 соединений в минуту.
 

pvvx

Активный участник сообщества
Далее сделаем сравнение любительской писанины для проца в сотни раз тормознее, с нашествием ардуинщиков в Linux.
Доморощенное, не ардуино подход, говорит о десятикратных улучшениях по показателям:
И RTL8710AF, при тех-же условиях (ip запроса заменен на имя "rtl871x0" и вставлено обращение к файлу "rtl.gif" для примерно одинаковой отдаваемой длины контекста):
Объем прошивки 251384 bytes с отладкой, heap ~130 килобайт, при работе:
Посмотреть вложение 4060
(потребление с дурным стабилизатором 5->3.3 - вычитать 5 мА, все sleep включены, но постоянный опрос по HTTP размера heap не дает упасть до 2.5 mA)
Посмотреть вложение 4057 Посмотреть вложение 4058 Посмотреть вложение 4059
Итого: 15 666 обращений в минуту к статической странице (файлу на web-диске) в сотни байт без парсинга.
А так-же посмотрим на ошибки в OpenWRT httpd. При тесте и после имеем простыню с тысячами TIME_WAIT:
Код:
root@FriendlyWrt:~# netstat -t
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 192.168.1.92:www        192.168.1.6:60557       TIME_WAIT
tcp        0      0 192.168.1.92:www        192.168.1.6:60607       TIME_WAIT
tcp        0      0 192.168.1.92:www        192.168.1.6:60540       TIME_WAIT
tcp        0      0 192.168.1.92:www        192.168.1.6:60674       TIME_WAIT
......
Т.е. что это базовая утилита Linux уже давно ничего не говорит. Писали явно ардуищики...
И httpd везет - он просто не успевает забить все порты, т.к. не достигает по производительности 65535 таких ошибок в TCP за 120 сек.
 

pvvx

Активный участник сообщества
Алексей. Про CGI или FastCGI даже не хочу измерять. Вы это можете сами - измерьте запрос вывода в web пусть таблицы route и опишете как оно, или как для этого применить ваши указания. :)
 

pvvx

Активный участник сообщества
И как промежуточный итог:
Вы считаете, что после таких советов, как вы привели и более глубоких знаний что творится ныне в реальном совте от нашествия Ардуинщиков не захочется ругаться матом?
От такого разгильдяйства в ПО и появляются всякие извращенцы типа Nikolz, т.е. современное ПО - это сплошные алгоритмические ошибки и написано безграмотными.
 

pvvx

Активный участник сообщества
Классический подход давно не работает - это как в случае с FastCGI вы получите ещё более slow систему. Не клюйте на рекламу – “Fast” это ныне = “Slow”.

Аналогично было с vfork() – оно было введено для ускорения, в целях оптимизации. Отношение скорости выполнения соответствовало переключению треда или ожиданию семафора, к запуску нового экземпляра ядра. Т.е. различие fork() к vfork() при его введении было более 10 раз. В vfork() работает аппаратура процессора с MMU и итоговая скорость равна поиску в системном кеше.

Но по итогу на сегодня его вырезали и заменили на fork() c опцией (вставили несколько if в код) и разница fork() к vfork() исчезла. Равна дублированию индексов открытых файлов и составляет до 10% в OpenWRT и подобных, а могла бы быть в сотни раз быстрее, т.е. до десятка us на современных ядрах. Как и отношение запроса-ответа web.
 

pvvx

Активный участник сообщества
Вообще не понятно, зачем там нужен MQTT?

Если охота какой-то простой и известный протокол, то без проблем годится и устаревший, но везде поддерживаемый Modbus TCP. :)

Любой тест TCP в локальной сети покажет, что время запрос-ответ в Modbus TCP составляет до 1 ms и в основном уходит на время обработки приема-передачи самих пакетов. Т.к. данный протокол ориентирован на запрос-ответ, то задержек и overhead у TCP стека не возникает. С передачей очередного пакета передается и TCP ACK. Т.е. лишних пакетов, не несущих полезной информации вообще нет. Есть только 3 пакета в начале сессии и 3 в конце, требуемые для поддержки самого TCP соединения, которое всё остальное сделает само.

Любой расчет и практика покажет, что при наличии от 4-х соединений кол-во транзакций (запрос-ответ) уже переваливает за 10 тысяч. В данном случае ограничение наступает по пропускной способности самой сети коммуникации. Т.е. даже проц в 100 МГц без проблем обслужит несколько десятков 9-ти осевых датчиков с опросом в 1000 замеров всех значений в сек от каждого.

MQTT на одном физическом устройстве этого и не снилось :p Распараллеленная система MQTT серверов может приблизиться к таким показателям, но не справиться в процессе сливания всех данных в один требуемый поток с необходимой малой задержкой для реалтайм задачи отображения бегающих чертиков по полученным координатам для пользователя на игровой монитор с 160 Гц. :)
 

pvvx

Активный участник сообщества
Я не призываю использовать Modbus TCP. Это в качестве примера, как самого простейшего и поддерживаемого протокола имеющего стандарты на передачу бинарных данных. SSL у него тоже имеется. Для обще-пользовательского сервера у него для современности есть ограничение в адресном пространстве, составляющем 250 по 65535 ячеек (250 виртуальных общедоступных сразу и для любого запроса данных устройств).

Нужен какой-то новый протокол для IoT вещей. Простой. Но его пока нет. Тот-же AdHoc всё пыжится, но не учитывает современных реалий – от и итогов никаких, и от него не предвидится.

Хорошо подойдет и websocket с SSL. SSL тут главное, т.е. стандартизирован для него. А вот передача бинарных, да и вообще любых данных в нем не стандартизирована.

Новая редакция HTTP пока не смогла завоевать рынок с её бинарными транзакциями…

Так что ждем нового протокола, а пока лепим что-то сами, на свои знания.
 

pvvx

Активный участник сообщества
Ещё для справки:
Различие однопоточного самописного web-сервера конфигурации на тупейшем контроллере и древней OpenWRT:
1585504203910.png
Для одного клиента:
1585503879493.png
Для 10 thread (хотя расчет велся до 5-ти клиентов за раз):
1585503884637.png
Т.е. имеем различие от 20 до 2-х раз, при разнице производительности CPU в 1008*4 МГц Quad-core Cortex-A7 к 200 МГц MIPS 4KEc V7.0. Разница в vfork() 548 us для у 200 МГц MIPS и 790 us для 1GHz Quad-core Cortex-A7 :)
И по возможностям и кол-ву затрачиваемых ресурсов httpd пока в полном пролете... О nix и прочих web монстрах и их кол-ве ошибок вообще лучше молчать.
 

pvvx

Активный участник сообщества
И сюда ардуинщики добрались:
Ставим Nginx:
1585507237021.png
Запускаем тест запроса просто страницы по умолчанию "/"
1585507405619.png
Заходим в консоль (добавляем apt-get install net-tools) и видим бесконечный список:
Код:
root@819eb0560fc5:/# netstat -t
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 819eb0560fc5:80         172.17.0.1:49460        TIME_WAIT
tcp        0      0 819eb0560fc5:80         172.17.0.1:49978        TIME_WAIT
tcp        0      0 819eb0560fc5:80         172.17.0.1:48546        TIME_WAIT
tcp        0      0 819eb0560fc5:80         172.17.0.1:49486        TIME_WAIT
tcp        0      0 819eb0560fc5:80         172.17.0.1:50070        TIME_WAIT
tcp        0      0 819eb0560fc5:80         172.17.0.1:50042        TIME_WAIT
tcp        0      0 819eb0560fc5:80         172.17.0.1:49142        TIME_WAIT
tcp        0      0 819eb0560fc5:80         172.17.0.1:49094        TIME_WAIT
....
т.е. через несколько секунд все 65535 портов исчерпаны и в RAM длинная цепочка TIME_WAIT структур у TCP стека :)
Это масенькая деталь из сотен, по чему оно тормозит.
PS: Остальные алго-ошибки *nix я описывать здесь не буду. Ныне на это требуют сикретное оповещение и если не исправят, то опубликовать через ...
Вот мне больше нечем заниматься... :)
 

pvvx

Активный участник сообщества
Не понятно для чего на каждый запрос запускать сторонний процесс для CGI, почему не использовать FastCGI, а сознательно грузить систему каждый раз поднимая новый процесс.
Если нет нужды запускать внешние процессы, а только обрабатывать на сервере запросы клиентов, совершенно не обязательно на каждый запрос на соединение строить новый поток.
На старте сервера строим несколько потоков, которые должны обрабатывать запросы клиентов, все эти потоки прослушивают один и тот-же порт, запросы клиентов начинают обрабатываться в незанятых потоках.
Если все потоки заняты, очередной клиент подключившись (если позволяет очередь backlog) ожидает обработки запроса когда освободится какой-либо поток.
Дык что - мало доказательств про то что вы пишите использовать в проф. оборудовании ни в коем случае случае нельзя если полностью не переработать своими ручками с нуля?
 

pvvx

Активный участник сообщества
И кроме алгоритмической ошибки, описанное есть большущая дырень в безопасности всех серверов с *nix. Можно сказать что в нем защиты просто нет. Кто знает, тот поймет как :)
 
Сверху Снизу