34 Stimmen

Skalierung einer Chat-App - kurzes Polling vs. langes Polling (AJAX, PHP)

Ich betreibe eine Website, auf der Benutzer miteinander durch den Browser chatten können (ähnlich wie bei Facebook Chat). Wie kann die Live-Interaktion am besten gehandhabt werden? (Derzeit läuft alle 30 Sekunden eine Umfrage, um die Online-Benutzer und neue eingehende Nachrichten zu aktualisieren, und eine weitere Umfrage auf Chat-Seiten alle Sekunde, um neue Nachrichten zu erhalten.)

Dinge, die ich in Betracht gezogen habe:

  • HTML5 Web Sockets: Habe ich nicht verwendet, da es nicht in allen Browsern funktioniert (nur in Chrome).
  • Flash Sockets: Habe ich nicht verwendet, da ich letztendlich mobile Web unterstützen wollte.

Derzeit verwende ich kurze Umfragen, weil ich nicht weiß, wie skalierbar AJAX Long Polling sein würde. Ich betreibe derzeit einen VPS-Server von servint (mit Apache). Sollte ich Long Polling oder Short Polling verwenden? Ich benötige keine absolut sofortigen Antwortzeiten (nur "gut genug" für eine Chat-App). Wird das häufige Kurz-Polling mit ein paar hunderttausend Benutzern meinen Server überlasten? Wie kann ich dies skalieren, bitte helfen Sie!

1 Stimmen

Ich weiß, dass Apache im Allgemeinen nicht gut mit vielen gleichzeitigen Verbindungen umgeht. Und ich bin mir auch bewusst, dass es möglicherweise andere Lösungen für dieses Szenario gibt (nodejs, usw.). Aber im Moment möchte ich vermeiden, die gesamte Anwendung neu zu schreiben.

0 Stimmen

Was ist mit der Implementierung mehrerer Lösungen für verschiedene Plattformen? D.h. wenn HTML5 unterstützt wird, verwendet der Browser HTML5, wenn Flash unterstützt wird, verwendet der Browser Flash, wenn keiner der beiden unterstützt wird, verwendet der Browser AJAX.

0 Stimmen

Sie könnten an diesem Beitrag interessiert sein urbanairship.com/blog/2010/09/29/linux-kernel-tuning-for-c50‌0k

45voto

Cory House Punkte 12460

Ein paar Anmerkungen:

  • Das Abfragen jede Sekunde ist übertrieben. Die App wird sich auch mit ein paar Sekunden Verzögerung zwischen den Abfragen sehr reaktionsschnell anfühlen.
  • Um den Datenbankverkehr zu reduzieren und die Antwortzeiten zu verbessern, erwägen Sie die Verwendung eines In-Memory-Caches zum Speichern nicht zugestellter Nachrichten. Sie könnten die Nachrichten immer noch in die Datenbank persistieren, der In-Memory-Cache würde einfach für Abfragen nach neuen Nachrichten verwendet, um Abfragen an die Datenbank alle x Sekunden von jedem Benutzer zu vermeiden.
  • Beenden Sie den Chat des Benutzers nach x Sekunden Inaktivität, um das Abfragen an Ihren Server zu stoppen. Dadurch wird sichergestellt, dass jemand, der ein Fenster offen lässt, nicht weiterhin Traffic generiert. Bieten Sie einen einfachen Link "Noch da? Weiter chatten." für Sitzungen an, die abgelaufen sind, und warnen Sie den Benutzer vor dem Ablauf, damit er den Zeitraum verlängern kann.
  • Ich würde vorschlagen, zunächst mit Polling zu beginnen, anstatt mit Comet/Long Polling/Sockets. Polling ist einfach zu erstellen und zu unterstützen und wird wahrscheinlich kurzfristig gut skalieren. Wenn Sie viel Verkehr haben, können Sie Hardware und einen Lastenausgleicher verwenden, um das Problem zu skalieren. Das gesamte Web basiert auf Polling - Polling skaliert mit Sicherheit. Es gibt einen Punkt, an dem die Komplexität von Alternativen wie Comet/Long Polling/usw. Sinn macht, aber Sie benötigen viel Verkehr, bevor die zusätzliche Entwicklungszeit/Komplexität gerechtfertigt ist.

23voto

Tass Skoudros Punkte 694

Dies ist etwas, das jeder einmal getan hat, bevor die Einführung von Cometd und Nodejs erfolgte.

Das Problem, wie ich es sehe, ist, dass PHP-Anfragen auf Apache sehr teuer sind. Wenn Ihre Chat-Anwendung alle Sekunde nach Nachrichten sucht, werden Sie sich in einer Situation wiederfinden, in der Apache nicht genügend Ressourcen hat, um auf Anfragen zu antworten. Der andere Bereich, in dem ich Verbesserungen sehe, ist die Verbesserung des Kontexts Ihrer Chat-Anwendung.

Warum wird es alle Sekunde aktualisiert, wenn nicht, um neue Nachrichten abzurufen? Was ist, wenn es keine Nachrichten gibt?

Einige Techniken, die Sie verwenden können;

  • Bieten Sie Ihren Clients einen leichten Endpunkt an, der einige Informationen über die Chat-Sitzung enthält, ob eine neue Nachricht aussteht, wie viele Nachrichten usw. Der Client kann darauf reagieren, indem er sofort aktualisiert oder nicht, wenn es keine neuen Nachrichten gibt. Über diesen Endpunkt kann ein einfaches JSON-Objekt über einen HTTP-Request bereitgestellt werden. Sie können sicher sein, dass diese Statusnachricht eine feste Größe hat und wenn sich die Antwort des Status nicht ändert, können Sie sie abbauen. Siehe nächste Nachricht.

  • Ein einfaches Absinken in Ihrem Javascript-Polling, wenn der Client einige Male hintereinander dieselbe Antwort vom Server erhält, können Sie das Polling um eine bestimmte Zeit erhöhen, derzeit sagten Sie, es sei jede Sekunde. Wenn Sie dies tun würden, würden Sie auf jede 2., 4., 6., 8., 10. Sekunde erhöhen. Sobald sich die Antwort vom Server ändert, setzen Sie das Absinken zurück.

Einige Optimierungen zum Überlegen;

  • Verwenden Sie einen PHP-Opcode-Cache wie APC.

  • Legen Sie ein niedriges Timeout für alle Anfragen fest, damit keine Anfragen Ihren Server blockieren.

  • Optimieren Sie Ihren PHP-Code, machen Sie ihn schlank und schnell.

  • Führen Sie einige Lasttests durch, um herauszufinden, wo Ihre Grenzen liegen.

  • Führen Sie häufig Benchmarks durch, um sicherzustellen, dass Ihre Anwendungen schneller werden.

  • Überprüfen Sie die Apache-Protokolle auf Anzeichen für den Gesundheitszustand der Anwendung und die Reaktionszeiten.

Wenn das Skalieren notwendig wird, fügen Sie einen neuen Server hinzu und verwenden Sie einen Lastausgleicher, um Anfragen zu verteilen. Ich habe Varnish und HAProxy mit großem Erfolg verwendet, und auch ihre Einrichtung ist nicht kompliziert.

1voto

Joseph Le Brech Punkte 6467

Wenn ich du wäre, würde ich eine Bibliothek wählen, die HTML5-Websockets verwendet, aber auf Flash-Sockets zurückgreift, wenn HTML5 nicht verfügbar ist. Der Browser, der durch das Raster fällt, sollte minimal sein.

Außerdem solltest du entweder PHP aufgeben oder es mit einem Thread-Socket-Server ergänzen, der entweder in Python oder Ruby mit em-Websocket geschrieben ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X