Priorität/Schweregrad: Selten, aber kritisch
Die Website wird nach vorübergehenden Datenbankfehlern bis zu 30 Minuten lang unbrauchbar. Seiten können aufgrund fehlender Client-Einstellungen, die JavaScript-Fehler verursachen, nicht richtig geladen werden.
Plattform:
- Betrifft: Alle Discourse-Installationen
- Beobachtet in: Produktionsumgebungen mit vorübergehenden Problemen bei der Datenbankkonnektivität
Beschreibung
Tatsächliches Ergebnis
Wenn ein vorübergehender Datenbankfehler auftritt (Verbindungs-Timeout, Pool-Erschöpfung, Netzwerk-Glitch), wird der Fehler 30 Minuten lang zwischengespeichert. Während dieser Zeit:
- Die Website wird nicht richtig geladen – Seiten erscheinen defekt oder funktionsunfähig
- Clientseitige JavaScript-Fehler treten aufgrund fehlender/ungültiger Einstellungen auf
- Jede Anfrage protokolliert „Nil client_settings_json from the cache for ‘client_settings_json\[git_version\]’“
- Leere Client-Einstellungen werden an den Browser zurückgegeben
- Dies setzt sich fort, auch nachdem die Datenbank vollständig wiederhergestellt ist
Erwartetes Ergebnis
Wenn ein vorübergehender Datenbankfehler auftritt, sollte das System den Fehler nicht zwischenspeichern. Sobald die Datenbank wiederhergestellt ist, sollte die nächste Anfrage die Client-Einstellungen erfolgreich abrufen und zwischenspeichern, und die Website sollte sofort wieder normal funktionieren.
Reproduzierbare Schritte
- Starten Sie eine Discourse-Instanz mit konfigurierten Client-Einstellungen
- Simulieren Sie ein Problem mit der Datenbankkonnektivität (z. B. Erschöpfung des Verbindungspools, Einführung einer Netzwerkverzögerung oder vorübergehende Blockierung von Port 5432)
- Machen Sie eine Anfrage, die
SiteSetting.client_settings_jsonauslöst (jede Seitenladung tut dies) - Beobachten Sie den Fehler: „Error while generating client_settings_json_uncached: \[database error\]“
- Seiten werden nicht korrekt gerendert, die JavaScript-Konsole zeigt Fehler im Zusammenhang mit fehlenden Einstellungen an
- Stellen Sie die Datenbankkonnektivität wieder her
- Machen Sie in den nächsten 30 Minuten weitere Anfragen. Sehen Sie weiterhin „Nil client_settings_json from the cache“-Fehler, obwohl die Datenbank in Ordnung ist
- Nach 30 Minuten läuft der Cache ab und die Website wird endlich wiederhergestellt
Benutzerauswirkungen
Die Website ist während dieser Zeit effektiv ausgefallen:
- Seiten werden nicht korrekt gerendert
- JavaScript-Anwendungen können aufgrund fehlender Konfiguration nicht initialisiert werden
Dies verwandelt einen 1-sekündigen Datenbank-Hiccup in einen 30-minütigen Ausfall.
Grundursache
In lib/site_setting_extension.rb fängt die Methode [client_settings_json_uncached](https://github.com/discourse/discourse/blob/main/lib/site_setting_extension.rb#L245-L276) Ausnahmen ab und gibt [nil](https://github.com/discourse/discourse/blob/main/lib/site_setting_extension.rb#L275) zurück. Dieses Nil wird 30 Minuten lang zwischengespeichert und bricht die Website.
Vorgeschlagene Korrektur
Ein Pull Request wurde eingereicht, um dieses Problem zu beheben. Die Korrektur erfordert eine einfache Änderung, um die Ausnahme erneut auszulösen, anstatt Nil zurückzugeben.
Warum es funktioniert:
- Das erneute Auslösen der Ausnahme verhindert, dass
Discourse.cache.fetchden Fehler zwischenspeichert - Die äußere
client_settings_json-Methode verfügt bereits über eine ordnungsgemäße Ausnahmebehandlung, die einen leeren String („“) zurückgibt, ohne ihn zwischenzuspeichern - Die Website kann während Datenbankproblemen weiterhin funktionieren (wenn auch eingeschränkt)
- Die Website wird nach der Wiederherstellung der Datenbank bei der nächsten Anfrage automatisch wiederhergestellt
- Die Korrektur stellt sicher, dass vorübergehende Datenbankfehler keine 30-minütigen Ausfälle verursachen.
Auswirkungen
Dieser Fehler betrifft alle Discourse-Installationen, die vorübergehende Datenbankprobleme haben:
- Erschöpfung des Verbindungspools während Traffic-Spitzen
- Netzwerk-Glitches zwischen Anwendung und Datenbank
- Datenbank-Failover-Szenarien (z. B. Umschaltung von primär/replika)
- Sperrkonflikte in der
site_settings-Tabelle - Abfrage-Timeouts aufgrund langsamer Abfragen
Schweregrad: Jedes dieser häufigen, vorübergehenden Probleme führt dazu, dass die gesamte Website 30 Minuten lang unbrauchbar ist, selbst wenn das zugrunde liegende Problem in Sekunden behoben wird.
Workaround
Wenn Sie dieses Problem gerade erleben, können Sie den Cache manuell löschen, um den Dienst wiederherzustellen:
In der Rails-Konsole
Discourse.cache.delete(SiteSettingExtension.client_settings_cache_key)