So beheben Sie Fehler im Discourse Forum /message-bus oder Long Polling

1. Problem

Wenn Discourse mit einem CDN konfiguriert ist, tritt ein häufiger Fehler auf:

/message-bus/204234de907442e8b77e153786a58e5b/poll
Verbindung fehlgeschlagen / Zeitüberschreitung / abnormaler Statuscode

Auswirkungen:

  • Benachrichtigungen schlagen fehl: Der rote Punkt (neue PM/Antwort) erscheint nicht mehr in Echtzeit; Updates kommen möglicherweise spät oder gar nicht an.

  • Echtzeit-Updates brechen: Neue Beiträge/Likes/Abstimmungen werden nicht automatisch aktualisiert; manuelles Aktualisieren der Seite ist erforderlich.

  • Benutzererfahrung sinkt: Meldungen wie „Verbindung verloren“ erscheinen; Interaktionen verzögern sich.

  • Erhöhte Serverlast: Das Frontend versucht ständig, Polls erneut zu senden, was den Ursprung belastet.

Grund: Discourse verwendet Long Polling, um die Echtzeitkommunikation aufrechtzuerhalten. Viele CDNs erzwingen Standard-Caching, verkürzte Timeouts, Herausforderungen/Firewall-Prüfungen oder Pufferung bei langen Verbindungen, was zu Unterbrechungen oder zwischengespeicherten Antworten führt, die das Echtzeitverhalten stören.


2. Allgemeiner Ansatz (Stabilität zuerst)

  • Domänentrennung: Leiten Sie MessageBus über eine dedizierte Domäne, die direkt mit dem Ursprung verbunden ist.

  • Reverse-Proxy-Schicht (Nginx):

    • Aktivieren Sie CORS für /message-bus.
    • Deaktivieren Sie Proxy-Pufferung, lockern Sie Timeouts, verbieten Sie explizit Caching.
  • CDN-Schicht (falls noch verwendet):

    • Konfigurieren Sie /message-bus/* mit keinem Caching, erweiterter Timeout-Dauer, keinen JS-Challenges/CAPTCHA/Ratenbegrenzungen und Cookie/Autorisierungs-Passthrough.
    • Oder umgehen Sie das CDN vollständig.

3. Implementierungsschritte

1) Discourse-Umgebungsvariablen konfigurieren

Bearbeiten Sie app.yml (normalerweise unter /var/discourse/containers/app.yml) und fügen Sie unter env:: hinzu/ändern Sie:

env:
  DISCOURSE_MESSAGE_BUS_REDIS_ENABLED: true
  DISCOURSE_LONG_POLLING_BASE_URL: "https://messagebus.example.com"

Änderungen anwenden (offizielle Bereitstellung):

cd /var/discourse
./launcher rebuild app

Erklärung:

  • DISCOURSE_LONG_POLLING_BASE_URL weist das Frontend an, die MessageBus-Domäne zu verwenden.
  • REDIS_ENABLED sollte aktiviert bleiben.

2) DNS & Zertifikat

  • Richten Sie messagebus.example.com direkt auf den Ursprung, um das CDN zu umgehen (Best Practice).
  • Richten Sie ein gültiges HTTPS-Zertifikat für die Domäne ein.

3) Nginx (MessageBus-Domäne) Reverse Proxy & CORS

Fügen Sie den folgenden Code zum Server-Block für messagebus.example.com hinzu oder aktualisieren Sie ihn:

location ^~ /message-bus {

    # (1) CORS-Preflight (OPTIONS) behandeln
    if ($request_method = OPTIONS) {
        add_header 'Access-Control-Allow-Origin' 'https://bbs.example.com' always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With,discourse-deferred-track-view-topic-id,discourse-present,discourse-track-view,discourse-deferred-track-view,x-silence-logger,dont-chunk,x-shared-session-key' always;
        add_header 'Access-Control-Max-Age' 1728000 always;
        add_header 'Content-Type' 'text/plain; charset=UTF-8' always;
        add_header 'Content-Length' 0 always;
        return 204;
    }

    # (2) An Discourse weiterleiten
    proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
    # oder, wenn Standalone:
    # proxy_pass http://127.0.0.1:3000;

    # (3) Doppelte CORS-Header verhindern
    proxy_hide_header Access-Control-Allow-Origin;
    proxy_hide_header Access-Control-Allow-Credentials;
    proxy_hide_header Access-Control-Allow-Methods;
    proxy_hide_header Access-Control-Allow-Headers;
    proxy_hide_header Access-Control-Max-Age;

    # (4) Normales CORS für Anfragen
    add_header 'Access-Control-Allow-Origin' 'https://bbs.example.com' always;
    add_header 'Access-Control-Allow-Credentials' 'true' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
    add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With,discourse-deferred-track-view-topic-id,discourse-present,discourse-track-view,discourse-deferred-track-view,x-silence-logger,dont-chunk,x-shared-session-key' always;

    # (5) Stabilitätseinstellungen für Long Polling
    proxy_read_timeout    120s;
    proxy_send_timeout    120s;
    proxy_connect_timeout 60s;

    proxy_buffering off;
    add_header X-Accel-Buffering no always;

    # (6) Caching explizit verbieten
    add_header Cache-Control "no-store, no-cache, must-revalidate" always;
}

:warning: Sicherheitshinweis: Wenn Access-Control-Allow-Credentials: true verwendet wird, darf Origin nicht * sein; es muss genau mit der Forum-Domäne übereinstimmen.


4) CDN-Regeln (falls Forum noch hinter CDN liegt)

Empfohlen: Kein Cache + erweiterter Timeout + Umgehung von WAF/Ratenbegrenzung für diese Pfade festlegen:

Beispiel für Regex:

^/(session|login|message-bus|admin|u|users)(/|$)

Richtlinie:

  • Kein Browser-/Knoten-Caching (no-store/no-cache).
  • Upstream/Lese-/Leerlauf-Timeout ≥ 60–120s.
  • JS-Challenge/CAPTCHA/Bot-Management deaktivieren.
  • Cookies und Autorisierungs-Header durchlassen (nicht entfernen).

4. Überprüfung des Erfolgs

1) Browser-Entwicklertools → Netzwerk

Auf der Forum-Seite:

  • Beobachten Sie /message-bus/…/poll.
  • Die Anfrage sollte für ca. 20–60 Sekunden „hängen“ und dann 200 (möglicherweise leer) zurückgeben.
  • Die nächste Poll-Anfrage wird automatisch ausgelöst.

Antwort-Header prüfen:

  • Access-Control-Allow-Origin: https://bbs.example.com
  • Cache-Control: no-store
  • Kein Age, X-Cache: HIT oder CF-Cache-Status: HIT (bedeutet nicht zwischengespeichert).

Häufige Probleme:

  • Fehler mit fester Dauer von 10s/30s → Edge/Origin-Timeout.
  • 504/524: Timeout.
  • 499: Unterbrechung der Zwischenschicht.
  • 403/401: WAF/Authentifizierung blockiert.

2) Schnelle Befehlszeilenprüfung (optional)

Konnektivität und Header prüfen (kein vollständiges Polling):

curl -I "https://messagebus.example.com/message-bus/health-check" \
  -H "Origin: https://bbs.example.com"

Hinweis: Tatsächliche Polls erfordern Sitzungskontext; dies überprüft nur CORS und Konnektivität.

1 „Gefällt mir“