Java Socket-Programmierung funktioniert nicht für 10.000 Clients

8

Ich kann mehrere Threads zur Unterstützung von Multi-Client-Funktionen in der Socket-Programmierung erstellen; das funktioniert gut. Aber wenn 10.000 Clients verbunden werden möchten, kann mein Server nicht so viele Threads erstellen.

Wie kann ich die Threads verwalten, so dass ich alle diese Clients gleichzeitig hören kann?

Wenn der Server in diesem Fall etwas an einen bestimmten Client senden möchte, wie ist es dann möglich?

    
Joachim Sauer 31.03.2009, 05:06
quelle

9 Antworten

11

Sie sollten Javas NIO-Bibliothek ("New I / O") für die nicht blockierende Netzwerkprogrammierung untersuchen. NIO wurde entwickelt, um genau das Problem der Server-Skalierbarkeit zu lösen, mit dem Sie konfrontiert sind!

Chris Peterson 31.03.2009 05:25
quelle
7

Hoch skalierbare Socket-Programmierung in Java erfordert die auswählbaren Kanäle in den "New I / O" - oder NIO-Paketen enthalten. Durch die Verwendung nicht blockierender E / A kann ein einzelner Thread viele Sockets bedienen, die nur auf die Sockets warten, die bereit sind.

Eine der besser skalierbaren Open-Source-NIO-Anwendungen ist die Grizzly -Komponente des Glassfish-Anwendungsservers. Jean-François Arcand hat eine Reihe von informativen, ausführlichen Blogbeiträgen über seine Arbeit an dem Projekt geschrieben und deckt viele subtile Fallstricke beim Schreiben ab diese Art von Software mit NIO.

Wenn das Konzept der nicht blockierenden IO für Sie neu ist, kann es sehr hilfreich sein, vorhandene Software wie Grizzly zu verwenden oder zumindest als Ausgangspunkt für Ihre Anpassung zu verwenden.

    
erickson 31.03.2009 05:25
quelle
6

Die Vorteile von NIO sind umstritten. Siehe Paul Tymas Blogeinträge hier und hier .

    
Julien Chastang 31.03.2009 16:08
quelle
4

Ein Gewinde-pro-Verbindung-Threading-Modell (Blocking Socket I / O) wird nicht gut skalieren. Hier ist eine Einführung in Java NIO, mit der Sie nicht blockierende Socket-Aufrufe in Java verwenden können: Ссылка

Wie der Artikel sagt, gibt es eine Vielzahl von Frameworks, so dass Sie nicht Ihre eigenen rollen müssen.

    
Peter 31.03.2009 05:26
quelle
2

Wie bereits erwähnt, ist 10.000 Kunden nicht einfach. Für Java ist NIO (möglicherweise mit einem separaten threadpool erweitert, um jede Anfrage zu bearbeiten, ohne den NIO-Thread zu blockieren), um eine große Anzahl von Clients zu verwalten.

Wie bereits erwähnt, können Threads, abhängig von der Implementierung, tatsächlich skaliert werden, aber es hängt sehr davon ab, wie viel Interaktion zwischen den Client-Verbindungen besteht. Massive Threads funktionieren mit größerer Wahrscheinlichkeit, wenn die Threads nur wenig synchronisiert sind.

Das heißt, NIO ist bekanntlich schwierig, 100% richtig zu machen, wenn Sie es das erste Mal implementieren.

Ich würde empfehlen, die Quelle für die Naga NIO-Bibliothek unter naga.googlecode.com auszuprobieren oder zumindest auszuprobieren. Die Codebasis für die lib ist klein im Vergleich zu den meisten anderen NIO-Frameworks. Sie sollten in der Lage sein, schnell einen Test zu implementieren, um zu sehen, ob Sie 10.000 Clients zum Laufen bringen können.

(Die Naga-Quelle ist auch frei, sie zu modifizieren oder zu kopieren, ohne dem ursprünglichen Autor zuzuschreiben)

    
Nuoji 01.04.2009 20:55
quelle
1

Dies ist keine einfache Frage, aber für eine sehr eingehende (Entschuldigung, nicht in Java) Antwort finden Sie hier: Ссылка

BEARBEITEN

Auch bei nio ist das immer noch ein schwieriges Problem. 10000 Verbindungen sind eine enorme Ressourcenbelastung für die Maschine, auch wenn Sie nicht blockierende Sockets verwenden. Aus diesem Grund haben große Websites Serverfarmen und Load Balancer.

    
grieve 31.03.2009 05:24
quelle
1

Warum verarbeiten Sie nicht immer nur eine bestimmte Anzahl von Anfragen gleichzeitig?

Nehmen wir an, Sie möchten maximal 50 Anfragen gleichzeitig bearbeiten (um nicht zu viele Threads zu erstellen)

Sie erstellen einen Threadpool mit 50 Threads.

Sie setzen alle Anfragen in eine Warteschlange (akzeptieren Sie Verbindungen, lassen Sie die Sockets offen), und jeder Thread, wenn es fertig ist, erhält die nächste Anfrage und verarbeitet sie dann.

Dies sollte leichter skalieren.

Wenn es notwendig ist, ist es auch einfacher, den Lastenausgleich durchzuführen, da Sie Ihre Warteschlangen für mehrere Server freigeben können

    
Martin 31.03.2009 16:04
quelle
0

Persönlich würde ich lieber ein benutzerdefiniertes I / O nicht blockierendes Setup verwenden, zum Beispiel einen Thread verwenden, um Clients zu akzeptieren und einen anderen Thread zu verwenden, um sie zu verarbeiten (prüfen, ob irgendwelche Eingaben verfügbar sind und Daten in die Ausgabe schreiben) .

    
Joe 02.07.2009 16:40
quelle
0

Sie müssen herausfinden, warum Ihre Anwendung bei 10.000 Threads versagt.

  1. Gibt es eine feste Grenze für die Anzahl der Threads in der JVM oder im Betriebssystem? Wenn ja, kann es aufgehoben werden?

  2. Haben Sie nicht genug Speicher? Versuchen Sie, pro Thread eine kleinere Stackgröße zu konfigurieren und / oder dem Server mehr Speicher hinzuzufügen.

  3. Noch etwas? Fix es.

Erst wenn Sie die Ursache des Problems ermittelt haben, können Sie es beheben. Theoretisch sollten 10.000 Threads in Ordnung sein, aber auf dieser Ebene der Gleichzeitigkeit bedarf es einer zusätzlichen Optimierung der JVM und des Betriebssystems, wenn Sie wollen, dass es funktioniert.

Sie können auch NIO in Betracht ziehen, aber ich denke, es kann auch mit Threads gut funktionieren.

    
Dobes Vandermeer 24.03.2012 13:02
quelle

Tags und Links