Socket ThreadPool oder Thread pro Client?

Stroker89

Bekanntes Mitglied
Hallo,

ich habe einen recht simplen Server geschrieben, der eigentlich nix weiter macht als XML Strings entgegen zu nehmen, diese auszuwerten, eine Aktion auszuführen und ein XML Ergebnis zurück zu schicken. Das ganze ist momentan so aufgebaut, dass der Server die Verbindung entgegen nimmt, und dann für jeden Client einen Thread aufmacht. Das Ganze funktioniert soweit auch eigentlich ganz gut.

Das System soll sehr viele User gleichzeitig behandeln können.
Angenommen es würden sich rein theoretisch 1000 User verbinden, würde der Server ja 1000 Threads aufmachen. Stellt das irgendwie ein Problem dar? Wo liegt die Grenze bei diesem Verfahren?

Jetzt habe ich auch von den ThreadPools gehört, die ja die Threads cachen können und man die Threadanzahl ja auf die Kerne/Prozessoren der jeweiligen Maschiene festsetzen kann, sehe ich das richtig? Wie steht das es dann hier um meine Mutliclientanforderung (viele Clients), wenn dann angenommen nur 4 oder 8 Threads im Pool sein dürfen? Was passiert wenn mehr Clients gleichzeitig kommen.

Wäre dankbar über eine Erläuterung.

Gruß
 
nun ... zunächst sind einzelne Threads pro Client bis einige 1000 threads kein problem ... allerdings muss man dafür der VM schon einige resourcen bereitstellen (über cli-parameter) ... aber auch hier ist irgendwann die grenze erreicht denn das system muss ja die unzahl an threads koordinieren ...

ein ThreadPool hingegen hat eine feste anzahl an Threads die wiederverwendet werden ...
der unterschied besteht hier das halt nicht für jede verbindung sofort ein neuer client-thread gestartet sondern automatisch auf den nächsten freien thread gewartet und dieser dann wiederverwendet wird ...

damit ist dann das system nicht ganz so beansprucht da weniger verwaltungsaufwand für eine unzahl an threads draufgeht sondern nur entsprechend der kernzahl ein sehr geringes vielfaches davon verwendet wird ...

das problem was sich daraus zwangsläufig ergibt ist die sequenzierung ... also das nicht mehr 1000 clients GLEICHZEITIG (was ja so eh nur "theoretisch" wäre) sondern halt immer nur soviele wie es threads im threadpool gibt ... und der rest wird dann hinten dran gestellt und muss warten bis die resourcen wieder frei sind ...

in wie weit das jetzt auswirkungen auf long-time ops hat und damit eventuelle socket-timeouts weis ich nicht ... wäre aber auf jeden fall ein punkt bei dem man sicher weiter erkundigen müsste ...

die andere möglichkeit wäre noch NIO ... aber da müssten dir andere helfen ... habe davon keine ahnung
 
Tausende Threads würde ich auf jeden Fall verhindern. Das bringt nur Probleme. Google mal nach "java nio channel selector".
 
Erstmal vielen Dank ihr beiden, für die Erläuterungen und Tipps 🙂 Ich werd mich mal erkundigen.
Das theoretisch war auf jetzt bezogen. Der Server wird definitiv so beansprucht.

Gruß
 
Ich hab mir jetzt mal ein paar Seiten angeschaut. In keinem der Beispiele werden eigene Threads für die Verbindung zum Client benutzt. Ist das bei NIO nicht mehr nötig oder was steckt dahinter?

@tfa: würdest du dann die Channels in einen festen ThreadPool, packen oder wie ist das gemeint?

Gruß
 
Nein, mit NIO brauchst du dann keine Threads für die Connections bzw. Channels. Richtig gearbeitet habe ich auch noch nicht damit. Programmier eins der Beispiele nach und vergiss erstmal den Threadpool. Den kannst du einführen, wenn die Datenverarbeitung mit den XML-Files länger dauert.
 
Das ganze Projekt was ich grad mach ist für meine Bachelorthesis. Ich denke mal, dass ich dort NIO als Alternative zu der konventionellen threadbasierenden Behandlung der Clients aufführen und erläutern werde.

Eventuell werde ich auch noch ein kleines Beispiel dazu schreiben mal sehen. Aber soweit erstmal vielen vielen Dank für deine Erklärung. 🙂

Gruß
 
Kleiner Tipp: Schau dir Apache MINA oder JBoss NETTY an. Java NIO zu Fuß ist wirklich nicht schön und die Performance ist schnell schlechter als bei Java IO wenn du's nicht richtig anstellst.

Kurz noch zu "Warum braucht IO keinen dedizierten Thread für einen Client":

Bei NIO wird ein "Event" ausgelöst wenn ein Client Daten schickt oder sich ein neuer Client verbindet (Non-Blocking-IO). Du kannst also die "Event"-Verarbeitung von einem Thread-Pool erledigen lassen und somit die Anzahl der Threads quasi selbst bestimmen. Wenn du 1000 Clients hast, aber nur 10 Threads dafür bereit stellst, könnte es unter Umständen sein dass ein Client sozusagen etwas warten muss bis auf dem Server ein Thread Zeit für ihn hat. D.h. hier gehen, wenn der Server am Limit läuft, nur einzelne Client-Verbindungen in die Knie.

Bei Java IO, wo du für jeden Client einen Thread hast, gehen eher alle Clients gleichermaßen in die Knie wenn die Last am Server zu hoch wird.

Kurzum: Für wirklich viele gleichzeitige Verbindungen ist NIO mit Java6 die einzige Wahl.

Mit Java7 gibt's nun auch AIO. Ist sehr mit NIO verwand, ist auch Non-Blocking, aber die tatsächliche IO-Verarbeitung passiert außerhalb von Java. Ist praktisch beim Senden: Du gibts ein paar Bytes zum Senden an das OS in Auftrag, und die erhälst einen Callback wenn das OS damit fertig ist. Somit triggert ein Callback das Senden des nächsten Paketes. --> ist nochmal performanter als NIO.

- Alex

[EDIT]Geht zwar im File-IO, aber für Netzwerk funktioniert AIO prinzipiell genau so:
http://www.java-forum.org/allgemeine-java-themen/131309-java7-faszination-file-aio-2.html#post860436[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:
ich habe neulich auf YT einen vlog eines uni-semesters gesehen in dem es zwar nicht speziell um IO / NIO / AIO ging ... jedoch wurde es als möglichkeit ebenfalls angesprochen ...

vom dozenten wurde erklärt das NIO / AIO nur noch teilweise bis eigentlich garnicht mehr in der VM-welt laufen sondern über bestimmte aufrufe einfach direkt ans betriebssystem weitergereicht werden ... und dadurch die optimierung des OS nutzen können was in der regel für den call selbst einen performance-gewinn bringt ... sowohl resourcen-management technich als auch geschwindigkeitsmäßig ...

jedoch gibt es eine stolperfalle : NIO / AIO sind sehr "low-level" (ausdrucksweise des dozenten) und man muss vieles was bei normalen IO bereits in der API gemacht wird selbst machen ... dadurch ergibt es meist mehr code als mit normalen IO ... und dadurch das mehr auszuführen ist und dies manchmal sehr kompliziert werden kann passiert es meist das bei "einfacher" anwendung von NIO / AIO eben dieser mehr-aufwand in der VM zu einer größeren performance-bremse wird als man durch NIO / AIO selbst an performance gewinnt

daher ist es meist ratsam wenn man NIO / AIO verwenden will bereits gut optimierte frameworks zu nutzen damit man sich den performance-vorteil nicht wieder durch eigenen unperformanten code wieder zu nichte macht ...
 
ich habe neulich auf YT einen vlog eines uni-semesters gesehen in dem es zwar nicht speziell um IO / NIO / AIO ging ... jedoch wurde es als möglichkeit ebenfalls angesprochen ...

vom dozenten wurde erklärt das NIO / AIO nur noch teilweise bis eigentlich garnicht mehr in der VM-welt laufen sondern über bestimmte aufrufe einfach direkt ans betriebssystem weitergereicht werden ... und dadurch die optimierung des OS nutzen können was in der regel für den call selbst einen performance-gewinn bringt ... sowohl resourcen-management technich als auch geschwindigkeitsmäßig ...

jedoch gibt es eine stolperfalle : NIO / AIO sind sehr "low-level" (ausdrucksweise des dozenten) und man muss vieles was bei normalen IO bereits in der API gemacht wird selbst machen ... dadurch ergibt es meist mehr code als mit normalen IO ... und dadurch das mehr auszuführen ist und dies manchmal sehr kompliziert werden kann passiert es meist das bei "einfacher" anwendung von NIO / AIO eben dieser mehr-aufwand in der VM zu einer größeren performance-bremse wird als man durch NIO / AIO selbst an performance gewinnt

daher ist es meist ratsam wenn man NIO / AIO verwenden will bereits gut optimierte frameworks zu nutzen damit man sich den performance-vorteil nicht wieder durch eigenen unperformanten code wieder zu nichte macht ...

Deine Ausführungen treffen voll und ganz für NIO zu. AIO ist aber komplett anders als NIO. Der "low level" Faktor ist hier quasi nicht vorhanden. Habe absolut keine großen Bedenken AIO ohne spezielles, ausgereiftes Framerwork einzusetzen. Bei NIO würde ich jedoch strengstens dazu raten ...

- Alex
 
Zuletzt bearbeitet von einem Moderator:
Soweit ich gelesen hab wird, in der aktuellen Alpha von Netty 4 AIO implementiert.
Für meine Arbeit hat das Wissen, was ihr mir mitgeteilt habt, momentan eh nur theoretischen Nutzen, da die endgültige Serverimplementierung nicht von mir durchgeführt wird.
Mich hat nur die Heransgehensweise an das Problem an sich interessiert.
Schön ist jetzt dass ich natürlich in meiner schriftlichen Arbeit, die genannten Techniken schön vergleichen kann 🙂

Gruß
 

Neue Themen


Zurück
Oben