Flask Socket.io Chat | Einige Fragen

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Einmal pro Sekunde ist ziemlich langsam aus client Sicht, und gleichzeitig 10000 Verbindungsanfragen pro Sekunde für den Server. Worin liegt der Vorteil gegenüber der Aufrechterhaltung dieser Verbindungen? Ob gunicorn das kann steht auf einem anderen Blatt.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@__deets__: Das Problem liegt nicht an gunicorn. CPU und RAM kommen locker mit ein paar Hundertausend Verbindungen klar. Auf der einen Seite ist es eine Hardware-Frage (wie viele Pakete kann ich pro Sekunde durch die Leitung quetschen) und eine Resourcenfrage des Linuxkernels (wie viele offene Verbindungen können in den internen Tabellen gehalten werden). Zweiteres kann man durch Tricks hochtreiben, bei ersterem taugt die Hardware für den Hausgebrauch nichts und man muß zu den teuren Karten greifen.
Zoja
User
Beiträge: 145
Registriert: Freitag 28. Februar 2014, 14:04

DasIch hat geschrieben:Das c10k Problem, also 10000 Verbindungen gleichzeitig zu haben ist schon eine Weile gelöst, bei 1000 Verbindungen ist man also noch lange nicht am Limit.

Grundsätzlich würde ich aber einfach empfehlen keine Websockets zu nutzen sondern einfach alle Clients pollen zu lassen, fragen die alle den Server nach updates einmal pro Sekunde dürfte die Latenz aus User Sicht durchaus akzeptabel sein und es ist viel einfacher damit serverseitig klar zu kommen.
So etwas habe ich mir gestern Abend auch überlegt. Ich könnte auf jeder Unterseite außer auf der Chat Seite eine AJAX Funktion einbauen, die alle 10 Sekunden ausgeführt wird und checkt, ob es ungelesene Nachrichten gibt. Falls ja, wird irgendwo eine Notification angezeigt, falls nein wird die Notification removed oder erst gar nicht angezeigt.

Ist dieser Ansatz nun besser / effizienter als mehrere Sockets auf zu haben? Muss man hier für nicht multithreaden? Ich nutze Flask und so weit ich weiß ist es nicht threaded.

Ich denke aber, dass es viel länger dauern wird mit diesem Ansatz, bis man schlechte Performance hat. Ich meine 1k Sockets ist auch schon eine ganze Menge. Man muss es erstmal schaffen 1k User gleichzeitig online zu haben. Für das AJAX polling sollte es doch auch weit über 1k gleichzeitgen Usern leicht sein alle 10 sekunden den Server anzufragen, oder?
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Sirius3 hat geschrieben:@__deets__: Das Problem liegt nicht an gunicorn. CPU und RAM kommen locker mit ein paar Hundertausend Verbindungen klar. Auf der einen Seite ist es eine Hardware-Frage (wie viele Pakete kann ich pro Sekunde durch die Leitung quetschen) und eine Resourcenfrage des Linuxkernels (wie viele offene Verbindungen können in den internen Tabellen gehalten werden). Zweiteres kann man durch Tricks hochtreiben, bei ersterem taugt die Hardware für den Hausgebrauch nichts und man muß zu den teuren Karten greifen.
Das kann ich nachvollziehen. Mir ging es um den Kontrast zwischen diese 10000 Verbindungen offen zu halten, was zwar internes Housekeeping bedeutet, aber zb keine Interruptfluten für eingehende Verbindungsanfragen erzeugt, und dem permanenten Pollen. Das das besser verkraftet wird kann ich mir schwer vorstellen.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

__deets__ hat geschrieben:Einmal pro Sekunde ist ziemlich langsam aus client Sicht, und gleichzeitig 10000 Verbindungsanfragen pro Sekunde für den Server. Worin liegt der Vorteil gegenüber der Aufrechterhaltung dieser Verbindungen? Ob gunicorn das kann steht auf einem anderen Blatt.
Der Vorteil ist dass du die Verbindungen wesentlich leichter über einen Load Balancer auf mehrere Server verteilen kannst. Deployments werden einfacher weil du dir keine Gedanken darüber machen musst dass Verbindungen verloren werden usw.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@__deets__: da hast Du recht. Mein nginx-Server hat gerade 200 Websocketverbindungen offen, die dann zu 200 Verbindungen zum Django-Server führen, alles ohne Probleme.

@Zoja: dagegen jeweils eine neue Verbindung mit TLS-Handshake dauert ziemlich lange. Daher auch mein Hinweis, eine Single-Page-Anwendung zu schreiben, so dass man die Websocketverbindung nur einmal aufbauen muß, nur eine Technologie nutzt.
Da Du das über Heroku deployst, ist sowieso vorgesehen, dass Du viele Worker benutzt, die unabhängig arbeiten.

Wie viele Nutzer erwartest Du denn parallel für Deinen Chat?

@DasIch: die Verbindungen von Websockets werden genauso über einen Load-Balancer verteilt. Bei 1000 Verbindungen pro Worker ist es statistisch gesehen sehr unwahrscheinlich, dass plötzlich nur die Verbindungen zu einem Worker hohen Load verursachen. Im Notfall kann man ja auch Websockets schließen, die dann vom Client automatisch neu aufgebaut werden.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

DasIch hat geschrieben: Der Vorteil ist dass du die Verbindungen wesentlich leichter über einen Load Balancer auf mehrere Server verteilen kannst. Deployments werden einfacher weil du dir keine Gedanken darüber machen musst dass Verbindungen verloren werden usw.
Ersteres gilt ja auch fuer ein Websocket-Szenario, letzteres ist ein generelles Problem - Laptop zu, Laptop auf, ICE-Internet hin, weg und wieder hin. Das muss ja auch eh geloest werden.

Damit kein Missverstaendnis entsteht: ich mache kein Web mehr, mich interessiert das wirklich weil ich es nicht mehr besser weiss ;) Was ich aber mache ist low-level-Linux-Kram, und die Menge an Interrupts und Systemaufrufen fuer Verbindungsaufbauten haben auch kosten.
Zoja
User
Beiträge: 145
Registriert: Freitag 28. Februar 2014, 14:04

Sirius3 hat geschrieben:@__deets__: da hast Du recht. Mein nginx-Server hat gerade 200 Websocketverbindungen offen, die dann zu 200 Verbindungen zum Django-Server führen, alles ohne Probleme.

@Zoja: dagegen jeweils eine neue Verbindung mit TLS-Handshake dauert ziemlich lange. Daher auch mein Hinweis, eine Single-Page-Anwendung zu schreiben, so dass man die Websocketverbindung nur einmal aufbauen muß, nur eine Technologie nutzt.
Da Du das über Heroku deployst, ist sowieso vorgesehen, dass Du viele Worker benutzt, die unabhängig arbeiten.

Wie viele Nutzer erwartest Du denn parallel für Deinen Chat?

@DasIch: die Verbindungen von Websockets werden genauso über einen Load-Balancer verteilt. Bei 1000 Verbindungen pro Worker ist es statistisch gesehen sehr unwahrscheinlich, dass plötzlich nur die Verbindungen zu einem Worker hohen Load verursachen. Im Notfall kann man ja auch Websockets schließen, die dann vom Client automatisch neu aufgebaut werden.
Ich glaube es wird sehr sehr lange dauern, bis ich 1000 gleichzeitige User erreiche. Aber die User sind lange auf der Webseite. Es ist eine Patreon ähnliche community.

Single Page macht hier Sinn (verstehe ich das richtig):

Es gibt Seite A und Seite B, User hat Seite A auf und im neuen Tab seite B, weil es keine Single Page Anwendung ist, werden 2 Sockets aufgemacht für den selben User? Bei Single Page ist es egal, ob die Seiten im neuen Tab auf sind, denn es ist die selbe Seite immer, nur der content wird ausgetauscht.

Frage: Gäbe es hier für SEO Probleme? Man will ja mit möglichst vielen Unterseiten vertreten sein. Macht man bei Single Page auch den jeweiligen content über unterschiedliche URL's erreichbar, nur wird dieser anders geladen?

---

Das mit dem TLS-Handshake höre ist zum ersten mal. Wird dieser gemacht/benötigt bei AJAX requests?
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Natuerlich wird ein TLS handshake gemacht - bei allen HTTPS-Verbindungen, und ohne die exakt gleiche Verbindung zu nutzen sollte eigentlich die Javascript same origin policy den Riegel vorschieben. Aber das ist nichts was *du* machen musst, das tut dein Browser schon fuer dich. Es geht nur darum, dass es einiges an overhead gegenueber einer stehenden Verbindung gibt.
Zoja
User
Beiträge: 145
Registriert: Freitag 28. Februar 2014, 14:04

__deets__ hat geschrieben:Natuerlich wird ein TLS handshake gemacht - bei allen HTTPS-Verbindungen, und ohne die exakt gleiche Verbindung zu nutzen sollte eigentlich die Javascript same origin policy den Riegel vorschieben. Aber das ist nichts was *du* machen musst, das tut dein Browser schon fuer dich. Es geht nur darum, dass es einiges an overhead gegenueber einer stehenden Verbindung gibt.
Achso, d.h. alle 10 sekunden für jeden user so eine AJAX pull zu machen, würde dazu führen, dass unnötige handshakes gemacht werden. D.h. also es wäre doch besser die Sockets zu nutzen und alle user auf jeder page zu connecten, verstehe ich das richtig?
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Alle 10 Sekunden ist viel zu langsam. Wenn ich mit dir chatte, dann schreibe ich dir Nachrichten im Sekundentakt. Und so etwas wie zB "tippt gerade"-Markierungen sind ja instantan.

Websockets sind fuer sowas gedacht, und wenn du mal wirklich so weit bist, dass das nicht mehr skaliert, dann hast du so viele User, dass du dir leisten koennen solltest, entsprechend dickerere Hardware zu kommisionieren oder die Investitionen in zB load-balancer und andere Skalierungstechniken sich rechnen.
Zoja
User
Beiträge: 145
Registriert: Freitag 28. Februar 2014, 14:04

__deets__ hat geschrieben:Alle 10 Sekunden ist viel zu langsam. Wenn ich mit dir chatte, dann schreibe ich dir Nachrichten im Sekundentakt. Und so etwas wie zB "tippt gerade"-Markierungen sind ja instantan.

Websockets sind fuer sowas gedacht, und wenn du mal wirklich so weit bist, dass das nicht mehr skaliert, dann hast du so viele User, dass du dir leisten koennen solltest, entsprechend dickerere Hardware zu kommisionieren oder die Investitionen in zB load-balancer und andere Skalierungstechniken sich rechnen.
Ja das sehe auch so.

Du hast mich trotzdem etwas falsch verstanden. Einen voll funktionierenden Chat, der mit Websockets arbeitet habe ich bereits, dieser ist aber nur auf einer Unterseite eingebunden, d.h. wenn user A auf der chat seite ist, kann er auch instant mit allen anderen usern chatten. Nur wenn user A jetzt nicht auf der Chat seite ist, dann ist er nicht connected, sollte aber trotzdem mitkriegen, ob neue Nachtrichten da sind, hierfür war das alle 10 sekunden updaten gedacht (auf allen Seiten außer chat seite). user A würde dann irgendwo angezeigt bekommen, dass es ungelesene chatnachrichten gibt und könnte wieder auf die Chat seite gehen, wo er wieder connecten würde.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ah. Naja, das hat Sirius3 ja schon beantwortet - alle grossen Kinder die das machen sind single page Anwendungen. Was SEO angeht kenne ich mich nicht aus, dazu gibt es aber bestimmt andere Foren.
Antworten