Mein FHEM "hängt" sich bei instabilem Internet auf

Begonnen von hasselh, 15 März 2026, 13:25:24

Vorheriges Thema - Nächstes Thema

hasselh

Hallo @rudolfkoenig,

ich monitore die Antwortzeit meiner FHEM Instanz über den Telnet Port. Diese liegt normalerweis unter 5 Millisekunden. Ein Watchdog startet die Instanz dann automatisch neu, wenn die Instanz für 60 Sekunden nicht antwortet. Und ich beobachte schon seit Jahren, dass diese Neustarts immer genau dann passieren, wenn auch mein Internet Aussetzer hat. Also wollte ich dem mal auf den Grund gehen...

Die Kommunikation ins Internet ist bei mir in FHEM wie folgt definiert:
attr global proxy 192.169.0.100:8118
attr global proxyExclude 127.0.0.1|192.168.*|192.169.*
attr global blockingCallMax 128

Den ausgehenden Port testweise zu blockieren hat bei mir nicht geholfen das Verhalten zu reproduzieren. Aber die ausgehende Kommunikation testweise gaanz langsam zu machen schon. Dazu führe ich den folgenden Code auf dem Rechner aus, auf dem auch FHEM läuft:
tc qdisc del dev eth0 root 2>/dev/null
tc qdisc add dev eth0 root handle 1: htb default 99
tc class add dev eth0 parent 1: classid 1:1 htb rate 20bps ceil 20bps burst 20 cburst 20
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
  match ip dst 192.169.0.100/32 \
  match ip dport 8118 0xffff \
  flowid 1:1

Was jetzt passiert, ist, dass nach einiger Zeit - speziell, wenn mein TelegramBot pollt oder wenn ich eine Nachricht über Telegram verschicke - quasi jegliche (auch lokale !) Kommunikation von FHEM anfängt "einzufrieren". Das betrifft bei mir telnet, mqtt, FHEMWEB und noch weitere Module. Da es zumindest in einem meiner Tests auch vorkam, dass FHEM auch mit deaktivierten TelegramBot einfriert, scheint es m.E. eher ein allgemeines Problem zu sein und nicht ausschließlich an dem TelegramBot zu liegen.

Hierzu ein paar Fragen:
- ist die Anzahl der parallel laufenden NonBlockingGet Aufrufe in FHEM irgendwie limitiert ?
- gibt es irgendeine Konfiguration, mit der ich das Verhalten von FHEM hierzu beeinflussen kann ?
- kann ich irgendwie die Anzahl der aktuell gleichzeitig laufenden "Kommunikations Threads" in FHEM herausfinden ?

Danke im Voraus, Hayo

Guybrush

ich würde mich weniger darum bemühen die symptome zu lindern und fhem ständig neu starten zu lassen. Die Ursache zu finden ist das einzig richtige. Schau dir mal deine DNS Settings an. Wenn du Abfragen auf Domains machst, helfen nonblocking Requests nicht, wenn die vorher erforderliche dns abfrage einen timeout generiert.

hasselh

#2
Danke dir. Das sehe ich auch so. Mein DNS läuft bei mir lokal:

attr global dnsServer 127.0.0.1

Und da ich ja einen Proxy verwende, läuft die Auflösung sowieso auf dem Proxy. Das Problem mit dem hängendem FHEM tritt auch nur so häufig auf wie das WAN Probleme hat (2-3x pro Quartal). Und es tritt auch dann auf, wenn ich den Proxy aus der Config rausnehme. Auf die Stabilität meines WANs habe ich halt nur bedingt Einfluss (der Antrag für einen 2. Provider läuft schon seit über einem Jahr). Und ein FHEM, das dann nicht mehr reagiert nervt halt...

Ich persönlich vermute, dass FHEM nur eine bestimmte Anzahl von parallelen nonblocking Requests zulässt und dann irgendwann komplett die Schotten dicht macht (nicht mehr erreichbar ist). Aber das ist nur eine Vermutung.

Gruß, Hayo

Guybrush

das glaube ich nicht, dass da ein Problem von fhem selbst ist. wüsste auch nicht, dass das limitiert wäre. Ein Problem mit deinem DNS System ist das wahrscheinlichste. sonst teste mal einen anderen dns server oder  trag hardcoded zum testen die ip adressen zu deinen verwendeten domains in deine hosts ein ums einzugrenzen..

rudolfkoenig

Zitat- ist die Anzahl der parallel laufenden NonBlockingGet Aufrufe in FHEM irgendwie limitiert ?
Nein, bzw. es sollte einen Fehler geben, wenn select keine weiteren Filedescriptoren akzeptiert.
Ich weiss nicht wo die Grenze liegt, ich vermute ueber 1000.

Zitat- kann ich irgendwie die Anzahl der aktuell gleichzeitig laufenden "Kommunikations Threads" in FHEM herausfinden ?
FHEM verwendet kein Multithreading, stattdessen werden alle Lese- und Schreiboperationen ueber den zentralen select abgewickelt.
Die Module duerfen nur dann lesen oder schreiben, wenn select zusichert, dass es nicht blockiert.
Leider halten sich nicht alle Module an diese Regel.
Folgendes gibt die Liste aller vom select ueberwachten Filedescriptoren aus, und danach entweder den Namen der dazugehoerigen FHEM Definition, oder die URL, wenn es ein HttpUtils_NonblockingGet ist.
{ join("\n", map { my $p=$selectlist{$_};; $p->{FD}.":".($p->{url} ? $p->{url}:$p->{NAME}) }  keys %selectlist) }HttpUtils_BlockingGet Aufrufe, oder andere, von den "bösen" Modulen blockierend ausgefuehrte Operationen sieht man damit nicht.

Zitatattr global dnsServer 127.0.0.1
Damit verwendet FHEM bei HttpUtils_NonblockingGet die eigene, nicht blockierende DNS "Bibliothek".

hasselh

#5
Danke @rudolfkoenig,

ZitatFolgendes gibt die Liste aller vom select ueberwachten Filedescriptoren aus, und danach entweder den Namen der dazugehoerigen FHEM Definition, oder die URL, wenn es ein HttpUtils_NonblockingGet ist.
{ join("\n", map { my $p=$selectlist{$_};; $p->{FD}.":".($p->{url} ? $p->{url}:$p->{NAME}) }  keys %selectlist) }

damit konnte ich jetzt NonblockingGet schon mal ausschließen. Die Liste ist kurz (15-20 Einträge), bevor FHEM einfriert, wenn ich den tc filter setze.

Zitatattr global dnsServer 127.0.0.1
Damit verwendet FHEM bei HttpUtils_NonblockingGet die eigene, nicht blockierende DNS "Bibliothek"

Wenn ich dich richtig interpretiere, sollte DNS in der Konfiguration mit dnsServer 127.0.0.1 eigentlich kein Problem sein, oder ? Lokal verwende ich sowieso nur IPV4 Adressen. Und Telegram und Co. gehen ja über den Proxy (FHEM löst die Adressen nicht lokal auf).

OK, eine Frage habe ich noch: Wenn attr global proxy gesetzt ist, verwendet die Kommunikation von FHEM mit dem Proxy auch keine blockierenden Operationen, oder ? Hintergrund: Wenn ich testweise nicht über den Proxy gehe (den Proxy habe ich aus Sicherheitsgründen mit einer Whitelist drin und direkte Kommunikation mit dem Internet ist bei mir blockiert) scheint es bei der Drosselung keine Freezes mehr zu geben.

Vielleicht gibt es ja jemanden, der seinen TelegramBot auch über einen Proxy betreibt und die oben beschriebene Drosselung ausprobieren mag ? tc ist auf Debian vorinstalliert und die Drosselung wird mit tc qdisc del dev eth0 root 2 jederzeit wieder aufgehoben. dst und dport sind natürlich individuell anzupassen:

tc qdisc del dev eth0 root 2>/dev/null
tc qdisc add dev eth0 root handle 1: htb default 99
tc class add dev eth0 parent 1: classid 1:1 htb rate 20bps ceil 20bps burst 20 cburst 20
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
  match ip dst 192.169.0.100/32 \
  match ip dport 8118 0xffff \
  flowid 1:1