Was ist ein Load Balancer?

Nehmen wir an, Sie hätten eine Java Webapplikation in Spring programmiert. Eine hochexklusive Homepage, welche dem Besucher die Frisuren aller Formel 1 Rennfahrer zeigt. Nun möchten Sie ihr Glanzstück dem Internet zeigen.

Im einfachsten Fall erstellen Sie ein aus ihrem Java Projekt eine WAR Datei (Web Archive). Dann brauchen Sie noch einen Server, der zum Beispiel eine Linux Distribution am laufen hat. Dort installieren sie einen Tomcat (siehe Tomcat oder Websphere?) und kopieren ihre WAR Datei in den Webapps Ordner. Beim Starten von Tomcat wird ihre Webapplikation automatisch entpackt und gestartet.

Unerhoffter Erfolg

Nach einigen Wochen schauen Sie sich die Benutzerstatistiken an und sehen, wie die Zugriffe auf ihre Seite explodiert sind! Alle wollen Formel 1 Rennfahrerfrisuren bestaunen! Ihr Server kommt mit den Anfragen nicht mehr nach. Was tun?

Mehr Server müssen her

Sie brauchen mehr Server und Sie brauchen ein Load Balancing!

Sobald Sie mehrere Server am Laufen haben spricht man von einem Server Cluster (oder auch Server Farm oder Server Pool). Ein Cluster ist eine Gruppe von Servern, die gleichzeitig eine Webapplikationen laufen haben und für die Aussenwelt so erscheinen, als ob es ein einziger Server wäre.

Zwischen der Aussenwelt und den Servern liegt dann der Load Balancer. Dies kann eine Software- oder Hardwarelösung sein.

Das Ziel ist es, die Hochverfügbarkeit zu gewährleisten. Wenn ein Server ausfallen würde, können die verbleibenden Server die Anfragen übernehmen. Ein weiteres Ziel ist die Skalierbarkeit. Wenn ihre Benutzerzahlen in den Himmel schiessen, werden Sie noch mehr Server benötigen, um den Ansturm an Besuchern auszuhalten. Das System muss also skalierbar und erweiterbar sein.

Wie funktioniert jetzt ein Load Balancer?

Wenn ein Besucher auf ihre Webseite geht, tippt er eine URL wie „www.suesseformel1frisuren.ch“ in den Browser. Der Domain Name Server (DNS) schaut dann in seinem Verzeichnis und findet die IP Adresse des Servers, etwa „200.0.0.121“, welche er dem Besucher zurückgibt. Das nennt man DNS Lookup.

Der DNS Server kann nun mehrere Adressen für eine URL speichern. Jede Adresse steht dann für einen Server im Cluster. Kommt nun eine Anfrage rein, schickt der DNS Server die Adresse des ersten Servers zurück. Bei der nächsten Anfrage die des zweiten Servers, dann des dritten, dann wieder der erste und so weiter. Das ist die Round Robin-Methode.

200.0.0.121
200.0.0.122
200.0.0.123

Was ist der Vorteil dieser Methode?

Der Vorteil davon ist, dass neue Server ganz einfach der Konfiguration hinzugefügt werden können.

Was ist der Nachteil bei der Server Affinität?

Server Affinität ist die Fähigkeit, die Benutzeranfragen an einen bestimmten Server zu senden. Ein Nachteil dieser Methode ist es nämlich, dass mehrere Anfrage des gleichen Benutzers an verschiedene Server geschickt werden können. Das HTTP Protokoll ist stateless, zwei aufeinanderfolgende Anfragen wissen nichts voneinander. Um die Kontrolle über die Session eines Benutzers zu behalten, kann der Server eine der folgenden Methoden verwenden:

1. Cookies
2. Versteckte Felder
3. URL Rewriting

Das Prinzip ist dabei jeweils dasselbe: Wenn ein Benutzer eine erste Anfrage macht, erstellt der Server ein Token, welches diesen Benutzer identifiziert. Dieses Token wird dann an den Benutzer geliefert, und dieser schickt immer das gleiche Token bei folgenden Anfragen. Somit kann der Load Balancer die Anfragen des gleichen Tokens immer an den gleichen Server schicken.

Ein Problem hierbei ist allerdings, dass der Browser die IP Adresse des Servers cached. Wenn dieser Cache abläuft, macht der Browser eine neue Anfrage und erhält gegebenfalls eine andere IP als vorher.

Was ist der Nachteil bei der hohen Verfügbarkeit?

Hat man einen Cluster mit 5 Servern und einer dieser Server geht offline, kann es dennoch vorkommen, dass Anfragen an diesen Server geschickt werden. Um dies zu verhindern prüfen moderne Router regelmässig, ob die Server noch angesprochen werden können.

Gibt es noch andere Load Balancing Algorithmen?

Ja, statt eines Round Robins könnte man etwa wählen, dass jeweils derjenige Server die nächste Anfrage erhält, welcher momentan am wenigsten offene Verbindungen zu Clients hat.

Oder man konfiguriert ein IP Hashing, bei dem man anhand der IP Adresse des Benutzers feststellt, an welchen Server er weitergeleitet wird.

Hardware und Software Load Balancers

Bei Load Balancers gibt es Lösungen als Hardware wie auch als Software.

Ein Hardware Load Balancer hat etwa den Vorteil, dass er selber eine virtuelle Ip Adresse besitzt, die er der Aussenwelt zeigen kann. Diese virtuelle Ip repräsentiert quasi den gesamten Cluster. Kommt nun eine neue Anfrage rein, überschreibt der Load Balancer den Request Header mit der effektiven Adresse eines Servers.

Der Vorteil ist hier, dass man Server einfach entfernen kann und nicht Gefahr läuft, dass dennoch ein Benutzer auf diesen Server connected – Schliesslich wird der gesamte Cluster durch die eine virtuelle IP repräsentiert. Das Problem ist, dass Hardware Load Balancer nicht in gesicherten HTTPS Verbindungen laufen, weil dort die Nachrichten SSL-verschlüselt sind und den Load Balancer daran hindern, auf die Informationen zuzugreifen. Die Server Affinität ist somit bei HTTPS nicht gegeben. Für die Entschlüsslung müsste ein Web Server Proxy vor den Cluster gehängt werden.

Software Load Balancer werden auch Application Delivery Controller (ADC) genannt, welche gut mit Virtual Appliances umgehen können – Also etwa ein Betriebssystem, Tomcat und Webapplikation als geschnürtes Paket.

Momentan mal! Virtual Applicances? Huh?

Genau. Am Anfang habe ich das einfachste Beispiel gemacht: Sie kaufen einen physischen Server, stellen ihn in einen Raum und installieren zum Beispiel eine Linux Distribution mit Tomcat auf dieser Maschine. Dort läuft dann ihre Webapplikation.

In den heutigen Firmen ist dieses einfache Beispiel aber mittlerweile ziemlich entfernt von der Realität. Stellen Sie sich vor, eine Firma müsste für jede Webapplikation eine bis mehrere physische Server unterhalten. Das wäre ein viel zu grosser Aufwand.

Stattdessen läuft heute mittlerweile so ziemlich alles virtualisiert – So virtualisiert, wie man sich das kaum vorstellen kann. Eine grosse Firma hat etwa eine gewisse Serverlandschaft zur Verfügung. Auf dieser Serverlandschaft laufen alle ihre Webapplikationen – Aber alle stets virtualisiert. Ihre Formel 1 Frisuren-Applikation ist dann etwa nur ein virtuelles Image, in dem schon alles enthalten ist: Applikation, Betriebssystem und Tomcat. So kann man die Applikation auf beliebig vielen Servern starten und wieder verschwinden lassen, ganz wie man es benötigt (Punkt Skalierbarkeit).

Liefert man eine neue Version seiner Applikation, macht das Entwicklungsteam oftmals gleich das Gesamtpaket (also das ganze Image) für den Betrieb bereit, welcher dieser nur noch deployen kann. Entgegen meinem Artikel Was ist DevOps? ist die Entwicklung und der Betrieb oftmals noch in verschiedenen Teams. Die Entwickler entwickeln, die Betriebsleute installieren.

Nun, es geht sogar noch weiter, aber ich muss wohl langsam zum Ende kommen. Weitere interessante Themen sind etwa Docker, bei dem man die Applikation auch noch vom Betriebssystem abkoppelt, oder serverless code, bei dem alles irgendwo in der Cloud läuft. Aber diese Geschichte erzähle ich ein anderes Mal.

Was ist eine Singlepage Applikation?

Bei einer Singlepage Applikation (SPA) handelt es sich um eine Webapplikation, die aus einer einzigen Seite besteht. Der Inhalt wird jeweils, je nachdem, was gerade angezeigt werden soll, dynamisch geladen.

Im Gegensatz dazu bestanden klassische Homepage aus mehreren Seiten (Multi Page Application – MPA), die untereinander verlinkt waren. Nun ja, in Zeiten von Cascading Style Sheets ist das Design nicht mehr so mühsam, selbst bei klassischen Homepages – früher jedoch musste man natürlich in jeder Html Seite neben dem eigentlichen Inhalt auch das Design der Seite einbauen. Hatte man dann eine Änderung, durfte man alle Seiten anpassen.

Ich erinnere mich noch an ein Projekt, welches ich vor langer Zeit in PHP gemacht hatte. Dabei hatte ich nur eine einzige Datei namens index.hmtl und habe den anzuzeigenden Inhalt jeweils über einen oder mehrere Parameter mitgegeben. Dies hatte den Vorteil, dass das Design und auch alle anderen querschnittlichen Aufgaben (Cross-Cutting Concerns) wie das Überprüfen des Benutzerlogins oder das Anzeigen des Headers und Footers in einer Datei gemacht wurde.

Ein weiterer Grund für mich war, dass man eine einzige grosse Seite hatte, die man von oben nach unten durchscrollen konnte, im Gegensatz zu einer Seite bestehend aus vielen Teilen (Frames).

Bei Multi Page Applikationen war es dann auch der Fall, dass jede Änderung zu einem Request zum Server geführt hat. Dies konnte zwar mit AJAX (Asynchronous Java And XML) ein wenig optimiert werden, so dass nur noch der Teil der Seite geladen wurde, welcher auch tatsächlich geändert hat. Beim Anzeigen einer komplett neuen Seite wird aber immer der gesamte Inhalt geladen.

Wie funktioniert denn nun eine Singlepage Applikation?

Eine Singlepage Applikation ist quasi die Fortführung der Multi Page Applikation + AJAX. Der Inhalt wird auf dem Server zusammengesucht, während die gesamte Benutzeroberfläche mit Javascript zusammengesetzt wird. Das Laden der Seiten wird so zwar schneller, allerdings bedeutet dies natürlich auch mehr Code, der auf der Clientseite ausgeführt wird.

Was ist der Vorteil einer Singlepage Applikation?

Ein grosser Vorteil ist, dass der Seitenkontext nicht immer neu geladen werden muss. Bei Applikationen mit mehreren Seiten wird jeweils die gesamte clientseitige Präsentationslogik beendet und auf der nächsten Seite neu geladen – Dies entfällt bei Singlepage.

Ein weiterer Vorteil ist es, dass das Backend einfach auf eine andere Plattform wie etwa Mobile übertragen werden kann.

Was ist der Nachteil von Singlepage Applikationen?

Ein Nachteil ist, dass jede Navigation des Benutzers in einem Request an den Server resultiert. Klickt der Benutzer zum Beispiel den „Zurück“ Knopf, erwartet er grundsätzlich ein sofortiges Ergebnis, da die Seite von vorhin ja schonmal geladen wurde und sich eigentlich nichts geändert hat. Bei einer Singlepage Applikation macht er jedoch einen neuen Request zum Server, um sich den Inhalt zu laden.

Der Grund dafür ist, wie gesagt, dass bei einer Singlepage Applikation das eigentliche Browsen mittels Javascript gemacht wird. Was ist nun, wenn der Benutzer Javascript deaktiviert hat? Dann wird er die Seite nicht verwenden können. Dieser Punkt bedeutet auch immer ein Zusammenspiel zwischen dem Backend und einer Javascript Komponente.

Wie kann eine Singlepage heutzutage gemacht werden?

Eine Singlepage Webapplikation kann heute etwa mit AngularJS und dem Spring Framework gemacht werden. Dabei übernimmt das Framework Aufgaben wie das Authentifizieren des Benutzers oder die Gewährleistung der Sicherheit.

Monolith oder Microservice Architektur?

In meiner Einführung in Microservices bin ich auf eben dieses Thema eingangen. Das Gegenteil von Microservices, quasi die „altertümliche“ Architektur, wird hingegen Monolith genannt.

Wenn man nun ein neues System designen möchte, nach welchen Kriterien entscheided man sich, ob man jetzt Microservices verwendet oder einen Monolith baut?

Die Eigenschaften von Microservices

Entscheidet man sich für eine Microservices Architektur teilt man eine Applikation in mehrere Komponenten, wobei jede Komponente individuell entwickelt und verpackt wird. Jede Komponente hat einen eigenen Prozess. Die einzelnen Services kommunizieren dabei etwa über eine REST Schnittstelle.

Die Eigenschaften einer Monolith Architektur

Bei einem traditionellen Monolith System gehören die Bausteine zu einer einzigen Applikation, die den Software Lifecycle durchlauft. Alle benötigten Komponenten sind darin enthalten und werden zusammen deployed. Die meisten Applikationen bestehen dabei mehr oder weniger aus einer Datenbank und einer serverseitigen Applikation. Die serverseitige Applikation hat dabei die meiste Logik, etwa das behandeln von HTTP Requests oder das Holen und Schreiben von Daten auf die Datenbank.

Die gesamte Businesslogik ist also an einem Ort. Natürlich besteht die Applikation aus verschiedenen Klassen und Interfaces etc., diese werden am Ende aber zu einem Paket verschnürt. In Java wird aus einer Webapplikation etwa ein WAR File erstellt, welches dann auf einem Tomcat Server deployed werden kann.

Die Nachteile eines Monoliths

Ist die gesamte Applikation eine einziges Stück, kann dieses natürlich über die Jahre ordentlich wachsen und unübersichtlich werden – oder sogar in einem degenerierten Design ausarten, welches nur noch schlecht zu korrigieren ist. Die Applikation mit ihren Anforderungen und Bugs muss immer von jemandem verwaltet werden, was sehr mühsam werden kann.

Was dazu kommt, ist das Ausliefern der Applikation. Da es eine einzige Applikation ist, muss bei jeder kleinen Änderung das gesamte Paket ausgeliefert werden. Dasselbe gilt für die Skalierung.

Gerade im Hinblick auf Microservices wird auch der Wechsel auf eine andere Technologie sehr mühsam bei einem Monolith. Hat der Monolith erst mal eine gewisse Grösse erreicht, wird kaum eine Firma mal fröhlich Geld in die Hand nehmen, um die ganze Applikation in einer anderen Technologie neu zu schreiben.

Monolith ist also schlecht, Microservices gut?

Genau! Microservices werden unabhängig voneinander entwicklet und ausgeliefert. Jeder Microservice wird individuell skaliert. Bei einer neuen Technologie kann ein Microservice einfach durch einen neuen ersetzt werden. So einfach kann das sein!

Wichtig: Jeder Microservice hat dabei seine eigene Datenbank! Das bedeutet gleichzeitig, dass jeder Microservice seinen eigenen Datenbanktyp einsetzen kann, sei das etwa eine relationale Datenbank oder NoSQL. Und jeder Microservice kann hinter einen eigenen Load Balancer gesetzt werden, um eine optimale Last zu gewährleisten.

Super! Ab jetzt nur noch Microservices!

Moment! Microservices haben ebenfalls ein paar Nachteile, welche ich hier auflisten möchte.

Ein Monolith hat den grossen Vorteil, dass die verschiedenen Komponenten ganz einfach miteinander kommunizieren können. Bei Java etwa ruft man einfach die Methoden der entsprechenden Klassen auf. Bei Microservices muss der Entwickler immer eine Schnittstelle gegen aussen für andere Microservices anbieten.

Ebenfalls ein wichtiger Punkt bei Microservices: Mehrere Microservices müssen sich gegenseitig finden beziehungsweise kennen – nicht ganz einfach, wenn die IP eines Microservice gegebenfalls ändern kann. Zu diesem Zweck braucht es einen sogenannten Service Discovery Mechanismus, damit die Microservices die Netzwerklokationen finden. Dies kann etwa eine speziell dafür eingesetzte Service Registry Datenbank sein, welche die Adressen aller Microservices kennt. Ein Microservice registriert sich dort, wenn er gestartet wird. Diese Datenbank muss natürlich immer verfügbar sein und darf seine IP nicht dynamisch wechseln 😉

Fazit

Als Fazit kann man sagen: Hat man das Glück und kann eine neue Applikation erstellen, muss man sich fragen, ob diese sehr gross und komplex oder eher klein und simpel ausfallen wird. Gross und komplex wäre dann eher was für verschiedene Microservices, während klein und simpel für einen Monolith sprechen würde. Oftmals ist die Realität aber so, dass man schon mit einem über die Jahre gewachsenen Monolithen zu tun hat. Ich probiere, herauszufinden, ob man einen Monolithen stückweise in Microservices migrieren kann oder ob dafür ein Big Bang notwendig ist.