Java-Massive-Multiplayer-Game-Server-Skalierbarkeit
Habe ich ein massive-multiplayer-online-Spiel für Android namens Infinite Black:
https://market.android.com/details?id=theinfiniteblack.client
In meiner Naivität, ich hatte erwartet, mäßige Wachstumsrate von über 1.000 Spieler im Monat, und benötigen, um zu verwalten, ~20 live-TCP/IP-clients tops.
Das Spiel hat unerwartet Explosives Wachstum mit über 40.000 neue Nutzer in einer Woche, und durchschnittlich ~300 live-verbindungen auf einmal, und wächst exponentiell.
Server-Architektur besteht aus 2 threads pro Verbindung (blocking read/write), ein ServerSocket-thread, um zu laichen neue Kunden, und einen controller thread, der fragt jedes client für neue Aktionen, gilt es die Spielwelt, dann spült die Daten wieder heraus, wenn Sie fertig.
Den server gebaut wird in Java, die ich bin nicht sehr versiert, insbesondere in einem high-stress-situation wie dieser. C# hat wirklich verwöhnt mich, wenn es um die Speicher-und thread-management.
Auf den Punkt zu bringen.. ich habe gerade bestellt zwei sehr leistungsfähige Systeme, um als dedicated game-Server und wollen zu maximieren der Ressourcennutzung. Viele der Informationen, die auf Java-Ressourcen-Konfiguration erwiesen, die irreführend, unrichtig oder veraltet sind.
Derzeit nutze ich -Xss512k als meine launch-argument, und verstehen, dass diese diktiert stack-Größe, die Zuteilung für jeden thread, den ich aber noch nicht vollständig verstehen alle, die es mit sich bringen kann. Welche tools oder Methoden verfügbar sind, um mir zu sagen, wenn ich bin hinausschießen und skalieren es runter? Was andere BefehlszeilenArgumente sollte ich beachten?
Den neuen Server mit 16gb RAM und i7-2600K Sandy Bridge 3.4 GHz-Prozessoren: Welche Optionen verfügbar sind, in die Konfiguration zu nehmen, so viel Vorteil wie möglich? Mein Ziel ist 1.200 online-Kunden auf einmal pro server (bis zu 2.400 threads).
Welche Art von unerwarteten Fallstricke und Probleme, sollte ich besorgt sein?
Ich gelesen habe, Wild widersprüchliche Geschichten auf maximale Fadenzahl: Werden sich die Dinge auseinander fallen, wenn ich versuche zu drücken bis zu 2.400 aktive threads?
Java scheint nicht, wie es entworfen wurde, für diese Art von Aufgabe. Sollte ich erwägen eine Migration der server auf eine andere Sprache?
Mir läuft der server im debug-Modus von Eclipse während der Entwicklung (igitt..)
Dies ist mein Eclipse .ini-Konfiguration:
--launcher.XXMaxPermSize
256M
-Xms256m
-Xmx1024m
- Tatsächlich, Java wurde für diese Aufgabe. 🙂
- Ja, wer würde jemals gedacht, bei der Verwendung von Java für die massiven Server? 😉 Aber das problem ist leider die ganze Lösung - 2threads/user einfach nicht korrekt skaliert, keine Sprache würde helfen.
- kegel.com/c10k.html, Wie groß moderne TCP-Server, um Zehntausende von TCP-verbindungen
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sie haben nicht deutlich gemacht, wo deine Zweifel herkommen.
Plurk Kometen: der Umgang mit mehr als 100.000 Gleichzeitige Verbindungen mit Netty (2009)
1999 habe ich implementiert eine Java-web-server, der verarbeitet die 40.000 gelbe Seiten Suchabfragen pro Stunde (der Server hatte 400 MHz-CPUs) und in 2004 habe ich die Entwicklung einer Java-Anwendung, die behandelt 8000 gleichzeitigen verbindungen pro server (auf einem dual-1,2 GHz-Sparc-Servern) gab Es sechs Tor-Servern und einem Haupt-server, die Steuerung und Zentralisierung der Ereignisse.
Ihrem Profil wird wahrscheinlich anders sein, aber ich kann sagen, dass die Java-Unterstützung wurde hohes Volumen von web-Servern, bevor Sie C# veröffentlicht wurde.
Persönlich würde ich nicht mehr als 10.000 gleichzeitige verbindungen pro server, aber das ist nur eine Faustregel, die unter Umständen nicht mehr halten. Sie können 32,000 threads in einer JVM. Auf Linux geht es nicht viel über diese. Allerdings hätte ich mir mehrere gateway-JVMs auf einem einzelnen server zu minimieren, Ihre vollständige GC-Zeiten (der beste Weg zur Minimierung der full GC-Zeiten ist zu verwerfen, weniger Müll, aber dies könnte erfordern mehr Aufwand)
Ich kann mir nicht vorstellen, warum das ein problem sein.
Denken, Sie brauchen, um jeden möglichen Befehl Linie parameter, wenn es wahrscheinlich ist, können Sie alle von Ihnen entfernt. Wenn du 4-gateway-JVMs mit 300 Verbindung jede, dieser können alle Speicher und Sie müssen nicht einmal angeben, die -Xmx Einstellung.
Sind Sie besser Fragen Sie sich, warum Sie dies glauben. Sie haben ein problem, das sollte einfach zu lösen oder eine Frage, die möglicherweise oder möglicherweise nicht unbegründet.
Konfigurieren Sie eclipse hat keine Sperre auf, wie ein Programm ausführen aus eclipse eingestellt ist.
BufferedOutputStream ist gut für die meisten Anwendungen und ist wahrscheinlich gut für bis zu 1000 verbindungen in einer JVM. Allerdings Java 1.4 (2002) Hinzugefügt NIO, die eine mehr Licht Gewicht für die Skalierung von Ihrem system zu 10.000 verbindungen und darüber hinaus.
BTW: Der server entwickelte ich im Jahr 2003 wurde auf der Grundlage NIO dispatcher, aber es ist ziemlich kompliziert, es sei denn, Sie verwenden eine standard-Bibliothek, wie Netty.
Da habe ich dann verwenden Sie eine single-thread-per-connection-Modell für die Sperrung NIO erfolgreich. Ich glaube, das ist einfacher zu verwalten als mit einem dispatcher und können, haben eine niedrigere Latenz Merkmale. Ich habe einen monitor-thread, der in regelmäßigen Abständen überprüft die verbindungen nicht blockieren, schreibt und schließt Sie, wenn Sie sind. Ich glaube nicht, dass Sie benötigen zwei threads pro Verbindung, aber ich glaube nicht, dass es einen Unterschied machen wird, in Ihrer situation, weil Sie nicht genug verbindungen pro server, egal.
Als glowcoder schlägt vor, haben Sie sich überlegt über UDP-für weniger kritische broadcast-Informationen?
In Java, jeder thread wird die gleiche Menge an Speicher auf dem stack-wie jeder andere thread. Dies bedeutet, dass Ihre Haupt-thread, sagen wir, es hat einen reservierten Größe von 32k (ich denke das ist Standard), wird die gleiche reservierte Größe wie Ihre Kommunikation von threads (die wahrscheinlich nur brauchen, 1k, wenn Sie über Sie denken!) Dies ist der Grund, warum Java kam mit nio - so brauchen Sie nicht ein thread pro Verbindung.
Geben wir 1g RAM Beispiel. Mit 32k pro thread, davon haben wir die Hälfte unserer Speicher für den stack und die Hälfte für die Haufen, die wir am Ende mit 512 verfügbar für stack. Das gibt uns Raum 16.384 threads. Dies bedeutet auch, dass unser thread-scheduler zu jonglieren und 16.384 threads. Dies erhöht die chance, dass einer der threads erhalten verhungert. Nun, wenn eine person bekommt verhungert, gut saugt, um ihm sein; wenn
main
bekommt verhungert, beschissen zu werden ... jeder!Mit nio, Sie haben... zwei threads. Haupt -, und Kommunikation. (Man könnte auch tun, ohne in den Kommunikations-thread, eigentlich...). Nun, eigentlich haben Sie wahrscheinlich ein bisschen mehr, als dass Sie ein Spiel haben, loop und so. Aber immer noch 10 threads ist viel einfacher zu planen, richtig als 16k threads!
Nio ist nicht unbedingt intuitiv zu lernen, aber es lohnt sich.
Eine Sache, die ich denken würde, wenn du nicht gehst, zu verwenden nio ist nur 1 thread pro Verbindung anstelle von zwei. Sie nicht brauchen, eine zweite für das schreiben: Sie können einen thread mit einer Warteschlange und müssen es tun, alle schreiben für alle clients. Das wird zumindest verdoppeln Sie Ihren Durchsatz für die Zeit.
flush()
ing, eine Steckdose sollte nicht blockieren, Ihre Java-code - vielmehr sollte es zu einem hardware-Ebene für die Verarbeitung muss damit es gepuffert Teil blockiert. Wenn Sie gehen, um manuell zu Spülen, sollten Sie nicht mit einerBufferedOutputStream
. Je nachdem, was Sie senden über, würde ich erwägenDataOutputStream
oderObjcetOutputStream
entsprechend.Müssen Sie nicht denken, im laden von Knoten, die weder in der Menge der threads.
1)
Wenn Ihr Spiele Maßstab für Millionen Benutzer, die Sie benötigen, cluster-Server loadbalanced durch einen registry -
2) Jeder Knoten muss sein, geringe Latenz, d.h. jedes eingehende Spieler-Nachrichten und Welt-update-Berechnung (1 tick) getan werden muss, milli Sekunden. Sehr machbar. Keine Notwendigkeit, eine monster-Konfiguration pro Knoten.
3) rufen Sie dies 30-mal pro Sekunde
=> Sie können Tausende Spieler gleichzeitig auf einem einzelnen Knoten und Skalierung von zehn thousansd Millionen mit region Segmentierung Dank einer registry vor, Ihre Infrastruktur, die dafür sorgen, dass Spieler die verbunden sind, um den besten ping Latenz-game-server.
Mit diesem Muster geladen 10 000 gleichzeitige Spieler auf Echtzeit-Spiel pro Knoten und +300 000 pro Knoten auf rundenbasiertes Spiel.
Engpass ist oft IO. Verwenden Sie die SSD für Datenbank-storage.
Java ist kein problem. 2400 thread ist ein problem. Lösen können Sie das problem mit der Schleife verbrachte Zeit und muss überlegen, unter Millisekunde tick loop.
HTH
Nuggeta admin - 100% Kostenlos hoch laden multiplayer-java-game-server