Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
phenolog opened this issue Nov 21, 2020 · 23 comments

Comments

@phenolog
Copy link

phenolog commented Nov 21, 2020

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
Copy link
Author

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

@sergejey
Copy link
Owner

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

@phenolog
Copy link
Author

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

@sergejey
Copy link
Owner

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

@phenolog
Copy link
Author

Нет не часто приходят.
В моем случае данные по температуре доходят до 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
Copy link
Owner

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

@phenolog
Copy link
Author

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

@phenolog
Copy link
Author

phenolog commented Dec 1, 2020

Сделал раздельные топики на чтение и запись. К сожалению ничего не изменилось.
Ниже лог вывода 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
Copy link
Owner

sergejey commented Dec 1, 2020

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

@phenolog
Copy link
Author

phenolog commented Dec 1, 2020

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

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

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

@phenolog
Copy link
Author

phenolog commented Dec 1, 2020

изображение

@phenolog
Copy link
Author

phenolog commented Dec 2, 2020

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
Copy link
Author

phenolog commented Dec 2, 2020

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

@sergejey
Copy link
Owner

sergejey commented Dec 2, 2020

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

@phenolog
Copy link
Author

phenolog commented Dec 2, 2020

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

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

@phenolog
Copy link
Author

phenolog commented Dec 2, 2020

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

@phenolog
Copy link
Author

phenolog commented Dec 2, 2020

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

@sergejey
Copy link
Owner

sergejey commented Dec 2, 2020

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

@phenolog
Copy link
Author

phenolog commented Dec 2, 2020

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

@phenolog
Copy link
Author

phenolog commented Dec 3, 2020

Проблема не в 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
Copy link
Author

phenolog commented Dec 3, 2020

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

@sergejey
Copy link
Owner

sergejey commented Dec 3, 2020

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

@phenolog
Copy link
Author

phenolog commented Dec 3, 2020

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants