Zunächst einmal möchte ich mich für irgendwelche dummen Fragen entschuldigen, ich lerne immer noch Netzwerkprogrammierung.Best Practice für Java UDP Multithreading
Ich habe nie viel Netzwerkprogrammierung gemacht, außer aus eigenem Interesse, und ich habe nur Javas Socket- und ServerSocket-Klassen verwendet. Bei diesen Klassen verwendeten die Paradigmen, die ich verwendete, einen einzelnen Java-Thread auf der Serverseite, der Verbindungen von Clients akzeptierte und diesen akzeptierten Socket dann an seinen eigenen Thread weitergab. Bei 100 gleichzeitigen Clients wären also (potentiell) 100 Threads vorhanden. Dann könnten der Client und der Server auf ihren eigenen Threads miteinander kommunizieren, getrennt von den anderen Komponenten des Systems.
Jetzt geben Sie den DatagramSocket ... Ich lerne gerade über TCP vs UDP, also gerade diese Klasse entdeckt. Es macht Sinn ... Sie hören auf Pakete an einem Port und senden Pakete über einen Port/eine Adresse. Der Körper enthält eine bestimmte Anzahl von Bytes und ist optional (Immer noch lernen, was die maximalen Körpergrößen sind und so). Aus den Online-Informationen habe ich erfahren, dass der Socket nach ANY-Paketen an diesem Port lauscht und die Quelle aus den Paket-Headern ableitet.
Das ist alles gut und gut, und ich bin komfortabel mit der Weiterleitung dieser Pakete an ihre eigenen Runnables in einem Pool, oder ihre eigenen Threads, etc. Was mich stört ist, dass mit TCP-Sockets jeder Thread (One of die 100 im obigen Beispiel) empfangen nur Nachrichten von der entsprechenden Quelle. Bei Datagram-Sockets gehen alle Pakete von jedem Client zu einem einzelnen Thread ... und dieser Thread ist dafür verantwortlich, die Arbeit zu teilen.
Wie würde so etwas in einem MMO-Spiel funktionieren ... sagen Sie, Sie haben einen Spielserver, der 5000 Spieler unterstützt und jeder Spieler 15 Pakete pro Sekunde ... Das sind 75.000 Pakete pro Sekunde, was für eine Single schwer scheint Thread zu behandeln. (Im Gegensatz zu 5000 Threads, die jeweils 15 pro Sekunde haben könnten). Offensichtlich könnte ein Thread die Pakete basierend auf Paketheadern und einem Client hashmap an die richtigen Stellen weiterleiten, aber ich bin nur unbehaglich, dass der Zuhörer-Thread selbst diese Logik ausführt.
Jetzt ist es möglich, dass TCP etwas Ähnliches tut (Ein Paket-Listener-Thread, der die Daten an den entsprechenden Socket weiterleitet), also verliere ich wirklich nichts. Ich schätze, die Wurzelfrage läuft auf ... Ist es möglich, mehrere Server-Threads den gleichen Port zu hören? Ich stelle mir zum Beispiel einen Load-Balancer vor, der die Pakete an verschiedene DataGramSocket-Listener round rockt (Eins für jeden Thread, vielleicht 3-4 Threads). Dann können diese Listener die Aufgabe des ursprünglichen einzelnen Threads übernehmen, der diese ungeordneten Pakete an die richtigen Stellen im Programm sendet (Beispiel, dieses Paket kam von 123.456.789.123 auf Port 6750 ... lasst uns unsere clientMap nachsehen, wo das hinführen sollte Geh ... Okay, sende an diese Thread-Paket-Warteschlange).
Ich denke die Antwort ist, dass solange der Thread alle Client-Pakete ist sehr leicht (nur Paket empfangen, delegieren, wiederholen), dann gibt es kein Problem, auch für hohe Datenaufkommen.
Danke!
EDIT: Nach einigem Nachdenken und Am_I_Helpful's Kommentar (Und jetzt Jamal H), realisierte ich, dass Sie dies auf einer Maschinen- oder Portebene abstrahieren können. Wenn Sie also 3000 Spieler haben, könnten Sie einen Load Balancer haben, der diesen Spieler zu einer bestimmten Maschine oder sogar zu einem bestimmten Port auf dem Rechner lenkt. Auf diese Weise können Sie X Anzahl von Server-Threads haben, die jeweils auf Pakete auf einem anderen Port warten. Spieler 1 kann den Port 7712 erreichen, Spieler 2 kann den Wert 7713 erreichen.
Sie haben immer verteilte Architektur für solche massive Architektur! Und UDP ist verbindungslos und schnell im Vergleich zu TCP. Außerdem sind die in Spielen ausgetauschten Pakete gewöhnlich leichtgewichtig. –
Ahh guter Punkt! Also welcher Server das Paket bekommt, könnte anders sein. Ich dachte Thread-Ebene, nicht Maschinen-Ebene. Könnte sogar Port-Ebene auf dem gleichen Computer gehen, vorausgesetzt, es war sehr groß (wie 16 Kerne, 64 GB Speicher). Dann könnten Sie einen Thread für jeden Port haben, den Sie gerade abhielten. Einem bestimmten "Spieler" könnte ein bestimmter Port zugewiesen werden. – user2770791