Datenbankfehler 30 Minuten lang in client_settings_json zwischengespeichert – Seite wird nicht geladen

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

  1. Starten Sie eine Discourse-Instanz mit konfigurierten Client-Einstellungen
  2. 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)
  3. Machen Sie eine Anfrage, die SiteSetting.client_settings_json auslöst (jede Seitenladung tut dies)
  4. Beobachten Sie den Fehler: „Error while generating client_settings_json_uncached: \[database error\]“
  5. Seiten werden nicht korrekt gerendert, die JavaScript-Konsole zeigt Fehler im Zusammenhang mit fehlenden Einstellungen an
  6. Stellen Sie die Datenbankkonnektivität wieder her
  7. 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
  8. 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:

  1. Das erneute Auslösen der Ausnahme verhindert, dass Discourse.cache.fetch den Fehler zwischenspeichert
  2. Die äußere client_settings_json-Methode verfügt bereits über eine ordnungsgemäße Ausnahmebehandlung, die einen leeren String („“) zurückgibt, ohne ihn zwischenzuspeichern
  3. Die Website kann während Datenbankproblemen weiterhin funktionieren (wenn auch eingeschränkt)
  4. Die Website wird nach der Wiederherstellung der Datenbank bei der nächsten Anfrage automatisch wiederhergestellt
  5. 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)
2 „Gefällt mir“

Guter Fang, ich werde an einer Lösung dafür arbeiten.

5 „Gefällt mir“

Sieht so aus, als wäre es zusammengeführt worden, vielen Dank.

2 „Gefällt mir“