In diesem Post möchte ich einmal erklären wie ein Minecraft Netzwerk funktioniert. Ich beziehe mich hier auf unsere IST-Situation. Wenn man heute ein Netzwerk neu aufbauen würde, dann würde man so ein Konstrukt nicht mehr anvisieren.
Der Post soll einerseits festhalten wie die Technologie funktioniert und wie sie zu dem Punkt gewachsen ist, an dem sie aktuell ist. Zusätzlich soll auch Lesern, die weniger mit der Technologie zutun haben, die bei uns verwendet wird, verständlich gemacht werden warum so ein Netzwerk nicht mit "java -jar spigot.jar" gestartet wird.
Ein einfacher Vergleich
Stellt euch einen einfachen Minecraft Server (auf dem man mit 4 - 5 Freunden spielt) wie einen Motor in einem Auto vor. Man dreht den Zündschlüssel oder drückt auf einen Knopf und der Motor startet. Wie das "Netzwerk" in Minecraft-Netzwerk bereits erkennen lässt, besteht es aus mehreren Minecraft Servern. Anfang 2016 waren es bei RewisServer ca. 640 Minecraft Server. Diese Server müssen verwaltet (start, stop, crash erkennung, tps check, usw.) werden. Dafür braucht man auch wieder Programme. 640 Minecraft server per Hand zu verwalten macht keinen Spaß. Letztlich kann man das mit einem kleinen Raketenstart vergleichen.
Basics
Ein Minecraft-Netzwerk besteht im Grunde aus 5 Komponenten. Proxies (z.B. BungeeCord), Gameserver/Lobbyserver (z.B. Spigot), Datenbank (z.B. MongoDB), Software die alles Verwaltet (gerne auch mal "Cloud" genannt) und Software die direkt die Minecraft Server startet, stoppt, etc. (auch "Daemon" genannt).
Proxies
Der Minecraft Client ist darauf ausgelegt auf einen Minecraft Server zu verbinden. Wenn man den Minecraft Server wechseln will, dann müsste man zuerst die Verbindung trennen, eine andere Adresse eingeben und dann wieder verbinden. Um nun aber einem Spieler die Möglichkeit zu bieten auf mehrere Server zu verbinden ohne, dass der Spieler selber die Verbindung trennen muss, setzt man einen Layer zwischen den Minecraft Client und Minecraft Server. Einen Proxy. Für den Minecraft Client gibt sich der Proxy als Minecraft Server aus.
Der Client verbindet zum Proxy und authentifiziert sich auch beim Proxy. Der Proxy selber stellt dann eine Verbindung zu einem Minecraft Server her und leitet dann die Pakete vom Spieler an den Server und vom Server an den Spieler. Wenn der Spieler nun z.B. von Lobby-1 in Lobby-2 geht, dann täuscht der Proxy dem Client einen Weltenwechsel vor (als würde man von der Overworld in den Nether gehen), trennt im Hintergrund die Verbindung zu Lobby-1 und baut eine neue Verbindung zu Lobby-2 auf.
Gameserver/Lobbyserver
Ich denke hier brauche ich nicht viel zu zu sagen. Ein Gameserver ist ein Minecraft Server. In der Regel findet eine Runde pro Minecraft Server statt. Nach Rundenende wird der Minecraft Server gestoppt.
Datenbank
Datenbank Management Systeme (kurz DBMS; ugs. Datenbanken) werden genutzt um Informationen zu speichern. Sie sind flexibel, skalierbar und ein single point of truth. Man kennt vielleicht noch aus alten Zeiten Plugins wie PermissionsEx. Dort wurden damals die Zuweisungen von Spielern zu Permission-Gruppen einfach in einer YAML-Datei gespeichert. Und das funktioniert auch. Allerdings wird soetwas bei Netzwerken schnell unübersichtlich. Man müsste diese Datei zwischen allen Minecraft Servern synchronisieren. Das würde auf Dauer zu Problemen führen. Das war natürlich nur ein kleines Beispiel. Weitere Beispiele für Daten, die in einer Datenbank landen sind Coins, Statistiken, Chatlogs, Replays, Bans, Clans, usw.
Jetzt muss man allerdings beachten, dass nicht jeder DBMS-Typ für jedes Anwendungszenario passend ist. Aber das ist ein Thema für einen anderen Post ...
Verwaltung "Cloud"
Damals und teilweise auch heute noch wurde für diese Software der Begriff "CloudServer" verwendet. Cloud ist auch heute noch ein Buzzword das für alles verwendet wird wo die eigentlichen Begriffe für den Endanwender zu kompliziert sind. iCloud oder Magenta Cloud sind File-Hoster. AWS Cloud oder Google Cloud sind dienstleister von Storage-Power, Compute-Power, CDN, uvm.. Es ist also nicht so wirklich fest definiert was "Cloud" eigentlich ist. Aber nun zurück zu unserer "Cloud" die nichts mit File-Hosting zutun hat. Diese Software, zu der eigentlich viel besser der Begriff "Zentralserver" passt, ist in der Grundfunktion dafür zuständig hunderte von Minecraft Servern zu orchestrieren. Wie ein Dirigent ein Orchester dirigiert, dirigiert der Zentralserver mit hilfe der Daemons die Minecraft Server und berücksichtigt dabei die Auslastung des (Linux-)Servers um diesen nicht zu überlasten.
Zusätzlich erlaubt der Zentralserver die Kommunikation der einzelnen Server untereinander. Jeder Proxy, Minecraft Server, Daemon hat eine Verbindung zum Zentralserver. Alle können untereinander Nachrichten austauschen.
Hier ein Beispiel wie es aktuell noch bei TheLotus läuft:
Wenn ein SpielerX sich mit /f tp zu einem FreundX teleportiert, dann schickt das RFriends-Plugin vom Proxy eine Nachricht an den Minecraft Server, auf dem sich der FreundX befindet, die einem Plugin dort sagt, dass es SpielerX direkt nach dem Betreten des Servers zu FreundX teleportieren soll. Nachdem die Nachricht gesendet wurde sendet der Proxy den Spieler auf den entsprechenden Server.
Daemons
Ein Daemon ist quasi der lange Arm des Zentralservers. Ein Daemon ist ein Verwaltungsprogramm, welches auf einem Linux-Server läuft und es dem Zentralserver ermöglicht auf jenem Server Minecraft Server zu starten. Der Zentralserver kann über die Daemons aber auch Informationen zu dem Linux-Server abrufen z.B. Arbeitsspeicher-Auslastung, CPU-Auslastung, SSD-Auslastung, usw. Anhand dieser Informationen entscheidet der Zentralserver ob auf dem jeweiligen Linux-Server noch Ressourcen für einen Minecraft Server sind.
RewisServer
Zu Beginn von RewisServer 2014 wurde das Grundsystem von Howaner programmiert. Dazu gehört der Zentralserver, die Daemons (damals noch Wrapper genannt), die Plugins zur Verbindung mit dem Zentralserver. Welcher Spielmodus wo gestartet wurde, war damals noch in den jeweiligen Konfigurationsdateien der Wrapper gespeichert. Die Wrapper konnten damals nicht viel. Minecraft Server starten, und wenn ein Minecraft Server gestoppt wurde den Minecraft Server neu starten. Zusätzlich konnte man noch ein CPU-Limit einstellen, sodass startende Minecraft-Server nicht den InGame-Servern die CPU-Leistung klauen. Letztlich waren das hunderte von Minecraft Servern die 24/7 liefen. Ob sie nun gebraucht wurden oder nicht.
Das war allerdings kein Problem, denn wir hatten die Rechenleistung sowieso. Die 26 BareMetal-Server gehörten damals uns und standen in einem Rechenzentrum in Frankfurt bei G-Portal. Dennoch hat dieses Setup zu Hochzeiten pro Monat Kosten im Vierstelligen Bereich verursacht. Circa 60% des Betrages waren Traffic-Kosten. Darauf folgte Strom, Housing kosten (Miete für den Stellplatz der Server) und kleinkram wie Remote-Hands (Techniker im Rechenzentrum).
Ein Problem was sich irgendwann zeigte war, dass wir SSDs sehr schnell verschlissen haben. Der Grund dafür war, dass das Dateiverzeichnis eines Minecraft Servers vor jedem Start aus einem Template Verzeichnis herauskopiert wurde. Wodurch die SSDs sehr viel schreiben mussten. Dies wurde irgendwann durch die Verwendung von OverlayFS behoben. Durch OverlayFS brauchten wir die Templates nicht mehr kopieren sondern konnten die Minecraft Server direkt mit den Templates starten. Sollte der Minecraft Server etwas schreiben (z.B. Konfigurationsdateien) dann würde OverlayFS diese Dateien in einem Separaten Verzeichnis speichern oder im Arbeitsspeicher halten und nach dem der Minecraft Server gestoppt wurde, wieder verwerfen. Zusammen mit diesem Update wurde die Logik so umprogrammiert, dass der Zentralserver die Minecraft Server On-Demand starten kann wodurch dann auch das CustomServer-Feature möglich wurde. Somit mussten nur noch eine minimale Anzahl an Minecraft Servern 24/7 laufen.
Nachteile
Zu Beginn dieses Posts habe ich gesagt, dass man ein solches System nicht mehr nachbauen würde, wenn man heute ein Minecraft-Netzwerk aufbaut. In diesem Abschnitt möchte ich näher darauf eingehen.
Single Point of Failure
Der Zentralserver ist wie der Name schon sagt ein zentraler Server. Ohne diesen Server funktioniert das Netzwerk nicht. Server können nicht mehr untereinander kommunizieren. Wenn der Zentralserver ausfällt, dann trennen die Proxies sofort die Verbindungen zu den Spielern und die Daemons killen alle Gameserver. Das bedeutet, dass beim Programmieren des Zentralservers besonders darauf geachtet werden muss, was man programmiert. Denn sollte ein Bug zum Crash führen bricht direkt das gesamte Netzwerk zusammen.
Automatische Skalierbarkeit
Das gesamte System ist nur in sich automatisch skalierbar. Wenn das System an seiner Grenze ist müssen händisch neue Server eingerichtet werden und die Daemons darauf gestartet werden. Umgekehrt kann das System aber auch nicht herunterskalieren. Wenn tagsüber 5 Linux-Server benötigt werden nachts aber nur einer dann gerät das System an seine Grenzen. Denn die nicht benötigten Server müssten von Hand abgeschaltet werden.
Monolith
Der Zentralserver ist aktuell als Monolith aufgebaut. Er orchestriert nicht mehr nur die Minecraft Server sondern macht auch noch eine Menge an anderen Dingen. Z.B. Elo-Berechnungen für Clans, TeamSpeak Bot, Discord Bot, usw. Das sind alles Faktoren die zur Instabilität führen können.
Abschließende Worte
Abschließend bleibt noch gesagt, dass sich aufgelistete Vor- und Nachteile auf uns und unser Ziel beziehen. Kleine Netzwerke brauchen keine Hochverfügbare Backend-Systeme und müssen auch nicht automatisch skalieren. Als die Software 2014 entwickelt wurde hat man sicherlich auch nicht damit gerechnet einmal das Zweitgrößte deutsche Netzwerk mit 7000+ Spielern zu sein.
Unser Ziel ist es das Netzwerk wieder auf einen Zeitgemäßen Zustand zu bringen, neue Minecraft-Versionen zu unterstützen um mit den neuen Features auch neue, spannende Spielmodi zu veröffentlichen und mit der Internationalisierung auch Spieler von außerhalb der DACH-Region anzusprechen. Dafür benötigen wir ein flexibles System welches unter Anderem basierend auf der Nachfrage automatisch skalieren kann.