sergejey / majordomo-mqtt

6 stars 13 forks source link

При записи топиков в брокер создается очень много зависших процессов apachу2 (Broken pipe) #27

Open phenolog opened 3 years ago

phenolog commented 3 years ago

SD Термостат при включении публикует в mqtt топик 30-50 раз в секунду. Создается много 30-250 зацикленных процессов apache2 strace -p xxx sendto(15, "\0\22/ESP32-51/output181", 21, 0, NULL, 0) = -1 EPIPE (Обрыв канала) --- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=6182, si_uid=33} --- Процессы apache2 забивают CPU, система не отвечает. Из ошибок только это "Maximum execution time of 180 seconds exceeded","file":"\/opt\/majordomo_0\/html\/3rdparty\/phpmqtt\/phpMQTT.php","line":436} Если ставлю в конец цикла cycle_mqtt.php задержку на полсекунды, то apache2 не множится, но топики читаются плохо. Комп быстрый i5, debian10 Предлагаю не публиковать повторно топик так часто. В коде есть заремленыый кусок DELETE FROM mqtt_queue.

phenolog commented 3 years ago

Не смог решить проблему на apache2 2.4.38-3+deb10u4. На nginx 1.14.2-2+deb10u3 работает нормально.

sergejey commented 3 years ago

А почему термостат так себя ведёт? Наверное это не совсем корректное поведение оборудования, если оно так часто данные публикует.

phenolog commented 3 years ago

Абсолютно с Вами согласен, некорректное. Но термостат это Simple Device Термостат. Он и публикует relay_status -> mqtt

sergejey commented 3 years ago

relay_status публикуется при каждом получении данных о температуре, т.е. можно конечно добавить какое-то ограничение по тому, что если relay_status не изменился, то не публиковать его или, по крайней мере, не так часто, но это дополнительная нагрузка на отслеживание того, когда в последний раз была публикация. Я так понимаю, что проблема из-за того, что данные температуры так часто приходят?

phenolog commented 3 years ago

Нет не часто приходят. В моем случае данные по температуре доходят до thermostat раз в 5 сек по цепочке: WiFi-iot --> mosquitto раз в 5 сек. MQTT --> simple device sensor_temhum. Обновляется раз в 5 сек, видно в Истории сенсора. Sensor_temphum sensor_pass () --> thermostat. Обновляется раз в 5 сек, видно в Истории термостата. Thermostat relay_status --> mqtt. Шлёт 1 со скоростью цикла. Попутно вопрос, а почему 0 не шлёт?

Как это сделано например в проекте wifi-iot: Термостат выставляет выход в 0 или 1. А раз в заданный промежуток времени (у меня 5сек) значения всех параметров датчики, GPIO тд. скидываются в mqtt. Таким образом поддерживается статус выхода термостата в mqtt в актуальном состоянии 0 или 1.

А если просто поставить в cycle_mqtt задержку sleep()?

sergejey commented 3 years ago

Исходя из описания, где-то что-то нештатно происходит, потому что у меня самого и на тех объектах, которые я обслуживаю, термостат работает по именно так, как задумано -- при поступлении информации от датчика температуры в термостат, значение сравнивается с заданной на термостате и в relay_status попадает либо 1 либо 0. Ни о каких записях со скоростью цикла речи не идёт. Кстати, такое возможно если у вас в MQTT получается "зацикливание", т.е. запись значения в MQTT инициирует событие считывания в MQTT -- такое возможно если для записи и считыния используется один и тот же топик MQTT.

phenolog commented 3 years ago

Да. Так и есть один топик на чтение и запись. Понял. Спасибо.

phenolog commented 3 years ago

Сделал раздельные топики на чтение и запись. К сожалению ничего не изменилось. Ниже лог вывода relay_status термостата в mqtt за одну секунду.

cat log_2020-12-01-cycle_mqtt.php.txt | grep set/output4| grep "11:54:28" 2020-12-01 11:54:28 Topic:/ESP32-51/set/output4 1 2020-12-01 11:54:28 CallAPI:/ESP32-51/set/output4 1 2020-12-01 11:54:28 Topic:/ESP32-51/set/output4 1 2020-12-01 11:54:28 CallAPI:/ESP32-51/set/output4 1 2020-12-01 11:54:28 Topic:/ESP32-51/set/output4 1 2020-12-01 11:54:28 CallAPI:/ESP32-51/set/output4 1 2020-12-01 11:54:28 Topic:/ESP32-51/set/output4 1 2020-12-01 11:54:28 CallAPI:/ESP32-51/set/output4 1 2020-12-01 11:54:28 Topic:/ESP32-51/set/output4 1 2020-12-01 11:54:28 CallAPI:/ESP32-51/set/output4 1 2020-12-01 11:54:28 Topic:/ESP32-51/set/output4 1 2020-12-01 11:54:28 CallAPI:/ESP32-51/set/output4 1 2020-12-01 11:54:28 Topic:/ESP32-51/set/output4 1 2020-12-01 11:54:28 CallAPI:/ESP32-51/set/output4 1

sergejey commented 3 years ago

У вас всё равно цикличная запись получается и устройство в MQTT-топик дублирует полученную команду установки, чего по идее не должно быть. Напишите полную конфигурацию, как должно быть -- какой топик у вас для чтения состояния, какой для установки значения и как оно сейчас привязано к объекту в модуле MQTT

phenolog commented 3 years ago

Спасибо за быстрый ответ

У вас всё равно цикличная запись получается и устройство в MQTT-топик дублирует полученную команду установки, чего по идее не должно быть. Напишите полную конфигурацию, как должно быть -- какой топик у вас для чтения состояния, какой для установки значения и как оно сейчас привязано к объекту в модуле MQTT

Подскажите, где задается в Термостате Топик для чтения состояния. У меня привязано только для записи mqtt: /ESP/set/output4 > relay_satus Куда привязать для чтения mqtt: /ESP/output4

phenolog commented 3 years ago

изображение

phenolog commented 3 years ago

SD Термостат при включении публикует в mqtt топик 30-50 раз в секунду. Создается много 30-250 зацикленных процессов apache2 strace -p xxx sendto(15, "\0\22/ESP32-51/output181", 21, 0, NULL, 0) = -1 EPIPE (Обрыв канала) --- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=6182, si_uid=33} --- Процессы apache2 забивают CPU, система не отвечает. Из ошибок только это "Maximum execution time of 180 seconds exceeded","file":"/opt/majordomo_0/html/3rdparty/phpmqtt/phpMQTT.php","line":436}

На Nginx то же самое.
Жду ответа, что делать?

phenolog commented 3 years ago

Я понял, что простые устройства (а может быть модуль mqtt) в принципе не работают с раздельными топиками. Пока не вижу, как сделать костыль, чтоб реализовать в MJD термостат с раздельными топиками. Мне это очень актуально, потому что начались морозы и дом надо отапливать.

sergejey commented 3 years ago

Дело в вашем устройстве, а не в MJD -- термостаты с MQTT работают без каких-либо проблем у меня на нескольких объектах с записью/чтением в разных топиках. У вас устройство публикует в MQTT событие записи в топик управления, что приводит к зацикливанию. Попробуйте ещё следующее -- удалить топик управления полностью, открыть топик чтения состояния и прописать путь записи прямо там. Например, топик чтения вида /sonoff/ESPURNA-2BAAC8/relay/0 , то поле Путь (Write) может быть /sonoff/ESPURNA-2BAAC8/relay/0/set

phenolog commented 3 years ago

Не помогло. Почистил базу чтоб иcключить влияние mysql. Разнес топики в MQTT, 1 перегрузил систему, включил термостат. Смотрю в MQTT_Fx оба конца публикует правильно. Через 5 минут 65 висящих процессов www-data по 15% CPU 3 Что виящий процесс делает. Пытается отдать данные. 5 Что в логе mqtt за одну секунду. 2 Эти CallAPI порождают childen's веб-сервера. Зачем столько вызовов?

У меня то же было на RPI. Решил, что не тянет CPU. Перешел на нормальный комп. Чистый debian. MJD тоже чистый, не переносил, ввел все устройства пальцем с нова.

phenolog commented 3 years ago

Я в Минске, могу с ноутбуком подъехать. А то утомительно переписываться.

phenolog commented 3 years ago

Или могу дать удаленный доступ

sergejey commented 3 years ago

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

phenolog commented 3 years ago

Сергей, то что вы повторили я понял и так. Вы имеете в виду мое устройство это "Простое устройство Термостат" ? Оно сыпет события на включение реле. В логах все видно. Ну ладно. Я Вас понял.

phenolog commented 3 years ago

Проблема не в mqtt а в Sensor_temphum. Он шлет sensor_pass() на Thermostat непрерывно. Связка работает неправильно: ESP/dhtt1 (5 сек)-> mqtt -> Sensor_temphum (непрерывно)-> Thermostat (непрерывно)-> ESP/set/output
Связка работает правильно: ESP/dhtt1 (5 сек)-> mqtt -> Sensor_temp (5 сек)-> Thermostat (5 сек)-> ESP/set/output

phenolog commented 3 years ago

Датчик_температуры работает нормально, А датчик_температуры_влажности требует доработки в части пересылки данных на связанное устройство.

sergejey commented 3 years ago

sensor_pass срабатывает как часть метода valueUpdated, т.е. правила обработки (и пересылки) значений применяются при обновлении (установки) значения сенсора. может быть сенсор данные как-то дополнительно обрабатывает и в себя же сохраняет?

phenolog commented 3 years ago

Не знаю. Есть 2 типа сенсоров. Сенсор температуры работает правильно. А комбинированный сенсор работает не так. Можно сравнить в коде, чем отличается.