Start / Seminare / Jakarta EE modernisieren
Modul
Moderne Application Server im Container
4 Kapitel in diesem Modul-Video · Laufzeit
Transkript
Der gesprochene Text dieses Moduls zum Mitlesen, Überfliegen und Durchsuchen. Ein Klick auf einen Zeitstempel springt an die Stelle im Video.
Moderne Application Server im Container
0:00 Nach der Entscheidung im letzten Modul sehen wir uns jetzt das erste der beiden möglichen Ziele genauer an: den Application Server, aber im Container und deutlich schlanker als früher. Für viele hört sich das nach einem Widerspruch an — Container gelten als leicht, Application Server als schwer. Das war einmal. Heute lässt sich ein Server so provisionieren, dass er nur noch die Subsysteme enthält, die eine bestimmte Anwendung tatsächlich braucht.
0:24 Wir sehen uns an, wie das geht, wie Konfiguration und Zustand aus dem Server herauswandern und was der Betrieb auf einer Plattform voraussetzt.
Moderne Application Server im Container
0:33 Dieses Modul ist der praktische Gegenentwurf zu der Vorstellung, Modernisierung müsse immer beim Framework anfangen. Vieles von dem, was man sich von einem Wechsel erhofft — schneller Start, kleinere Angriffsfläche, reproduzierbare Auslieferung — lässt sich auch ohne Architekturbruch erreichen. Und was wir hier lernen, brauchen wir in Modul vierzehn wieder, wenn der migrierte Dienst auf dieselbe Plattform kommt.
Schlanke Serverkonfiguration
0:56 Fangen wir mit dem Server selbst an. Die entscheidende Frage lautet: Warum sollte er Subsysteme mitbringen, die diese Anwendung nie benutzt? Moderne Server beantworten diese Frage inzwischen selbst: Sie leiten ihre Konfiguration aus dem Deployment ab, statt umgekehrt das Deployment in einen fertigen Server zu legen. Denken Sie an einen Werkzeugkoffer. Früher hat man den ganzen Koffer mitgenommen, weil man nicht wusste, was gebraucht wird.
1:22 Ein provisionierter Server dreht das um: Er schaut sich die Anwendung an und packt nur ein, was sie tatsächlich braucht. WildFly Glow ermittelt dafür aus dem Deployment die nötigen Galleon-Feature-Packs und Layer. Bei Open Liberty läuft es über die server.xml und das Feature-Werkzeug: Sie benennen die Features, und das Werkzeug installiert genau diese.
1:42 In beiden Fällen entsteht die Serverkonfiguration aus einer Datei — reproduzierbar und versionierbar. Die Reihenfolge dieser vier Schritte ist der eigentliche Fortschritt gegenüber früher. Früher stand am Anfang ein Server, den jemand eingerichtet hatte, und das Deployment kam hinein. Heute steht das Deployment am Anfang, und der Server wird daraus abgeleitet.
2:03 Damit dreht sich die Abhängigkeit um: Nicht die Anwendung passt sich dem Server an, sondern der Server der Anwendung. Und weil alle vier Schritte in einem Skript stehen können, ist das Ergebnis wiederholbar. Ein Serverupdate wird damit zu einem Neubau statt zu einem Eingriff — das ist ein enormer Unterschied im Betriebsalltag.
2:22 Worauf es hier ankommt, ist der erste Aufruf und das, was er ausgibt. Der Scan meldet nicht nur, welche Layer gebraucht werden — er meldet auch, welche Fähigkeit er im Deployment gefunden, aber keinem Layer zuordnen konnte. Genau diese Meldungen sind Ihre Fundstellen: Dort nutzt die Anwendung etwas, das der schlanke Server nicht abdeckt. Der zweite Aufruf baut daraus ein Image.
2:45 Das Angenehme daran: Sie bekommen das Ergebnis in Minuten und können es sofort ausprobieren. Was früher eine Woche Serveradministration war, ist heute ein Skriptaufruf mit prüfbarem Ergebnis. Vier Punkte, und der vierte ist der, der im Betrieb den größten Unterschied macht: Ein Update des Servers wird zum Neubau statt zum Eingriff.
3:05 Denken Sie an das, was heute passiert, wenn ein Sicherheitspatch für den Server ansteht — Wartungsfenster, Ausfall, Handarbeit, Risiko. Bei einem provisionierten Server bauen Sie ein neues Image mit der neuen Serverversion und rollen es aus. Dazu kommt der Sicherheitsgewinn: Weniger Subsysteme bedeuten weniger Angriffsfläche und weniger Bibliotheken, für die überhaupt Schwachstellen gemeldet werden können.
3:27 Das ist messbar, und es beruhigt die Sicherheitsabteilung. Der erste Punkt hebt den ganzen Gewinn wieder auf: Der provisionierte Server wird nachträglich von Hand ergänzt. Dann haben Sie zwar ein Image, aber niemand kann es aus der Beschreibung noch einmal erzeugen. Alles muss zurück in die Provisionierungsdatei. Punkt zwei ist der typische Fehler beim ersten Versuch: Ein Layer fehlt, und das merkt man nicht beim Start, sondern beim ersten Aufruf der betroffenen Funktion — oft der Batch-Lauf, oft nachts.
3:56 Testen Sie deshalb jede Funktion aus dem Inventar mindestens einmal an, bevor Sie das Image freigeben.
Konfiguration, Secrets und Zustand
4:03 Jetzt zu dem Teil, der bei der Containerisierung tatsächlich Arbeit macht — und den man am besten sofort richtig macht, weil man ihn sonst zweimal macht. Es geht um alles, was sich zwischen zwei Umgebungen unterscheidet: Konfiguration, Geheimnisse — und, am schwierigsten, den Zustand. Ein Image ist wie ein gedrucktes Buch: Was drinsteht, steht fest. Alles, was sich je Umgebung unterscheidet, gehört deshalb nicht hinein.
4:28 Endpunkte, Zugangsdaten und Grenzwerte kommen zur Laufzeit dazu — über Umgebungsvariablen, ConfigMaps und Secrets. Der Gewinn ist konkret: Dasselbe Image läuft unverändert in Test, Abnahme und Produktion. Und das ist mehr als Bequemlichkeit. Es bedeutet, dass Sie in Produktion exakt das betreiben, was Sie getestet haben — nicht etwas Ähnliches, das aus derselben Quelle noch einmal gebaut wurde.
4:54 Diese Gegenüberstellung ist eine sehr praktische Prüfliste. Nehmen Sie jede Einstellung Ihrer heutigen Serverkonfiguration und ordnen Sie sie einer der beiden Spalten zu. Die Faustregel lautet: Wenn sich der Wert zwischen zwei Umgebungen unterscheidet, gehört er nach rechts. Wenn er überall gleich ist, darf er nach links.
5:13 Interessant wird es bei den Grenzwerten — Poolgrößen, Zeitlimits, Puffergrößen. Die stehen oft im Server, unterscheiden sich aber je Umgebung. Und genau die werden beim ersten Containerisierungsversuch regelmäßig übersehen, weil sie niemandem als Konfiguration erscheinen. Das ist der Teil, der unterschätzt wird. Konfiguration herauszuziehen ist Fleißarbeit — Zustand herauszuziehen ist Entwurfsarbeit.
5:37 Sitzungen im Serverspeicher überleben kein Rolling Update, weil die Instanz mit den Sitzungen verschwindet. Dateien im Container verschwinden mit dem Container. Und der dritte Punkt ist der, der bei Zählwerk am meisten weh tut: Timer dürfen bei mehreren Instanzen nicht doppelt starten. Solange genau ein Server lief, war das kein Thema.
5:57 Sobald zwei Instanzen laufen, legt der nächtliche Ableselauf jeden Auftrag zweimal an — und niemand merkt es sofort. Die Logik dieser Tabelle ist eine Umzugsliste für Zustand: Wo liegt er heute, und wo muss er hin? Beachten Sie die letzte Zeile, sie ist die entspannteste: Ein Cache darf im Container kalt starten. Das kostet nach jedem Rollout etwas Leistung, und in den meisten Fällen ist das völlig in Ordnung. Man muss nicht jeden Zustand retten.
6:24 Die Zeile darüber ist die unangenehme: Beim Timer müssen Sie sich entscheiden — entweder läuft er nur in einer Instanz, oder eine externe Steuerung übernimmt. Beides ist Arbeit, aber die Entscheidung lässt sich nicht umgehen. Punkt zwei ist der, den ich am häufigsten sehe: Sitzungsbindung wird über den Lastverteiler erzwungen, statt das Problem zu lösen.
6:45 Das funktioniert — bis eine Instanz ausfällt oder ein Rollout läuft, und dann verlieren genau die Nutzer ihre Sitzung, die gerade aktiv waren. Es ist eine Verschiebung, keine Lösung. Und Punkt vier gehört zu den leisen Datenverlusten: Logdateien werden im Container geschrieben und sind beim Neustart weg. Ausgerechnet die Logs des abgestürzten Containers, die Sie zur Fehlersuche bräuchten. Schreiben Sie auf die Standardausgabe und lassen Sie die Plattform einsammeln.
Betrieb auf der Plattform
7:12 Bleibt der Betrieb. Die Plattform trifft ständig Entscheidungen über Ihren Container — und sie trifft sie anhand von drei Prüfpunkten, die Sie liefern müssen. Wer diese drei verwechselt, bekommt Neustarts, wo eigentlich nur für ein paar Sekunden kein Verkehr hätte ankommen sollen. Die Plattform prüft einen Container über Health Endpoints und entscheidet daran, ob er Verkehr bekommt und ob er neu gestartet wird.
7:35 Open Liberty stellt dafür über MicroProfile Health die Pfade health/live und health/ready bereit; Startup-Prüfungen decken langsam startende Anwendungen ab. Und das ist bei migrierten Enterprise-Anwendungen ein wichtiger Punkt: Ein Application Server mit einer großen Anwendung braucht durchaus eine Minute zum Start. Ohne Startup-Prüfung schlägt die Plattform zu früh Alarm und startet neu — in einer Endlosschleife, die aussieht wie ein Absturz.
8:00 Die entscheidende Logik steht in der dritten Spalte: Die drei Prüfungen haben völlig verschiedene Konsequenzen. Bereitschaft nimmt nur Verkehr weg, Lebendigkeit startet neu. Und daraus folgt die wichtigste Regel dieses Kapitels, die Sie in der Fußzeile finden: Eine Lebendprüfung, die die Datenbank abfragt, startet Ihren Container neu, wenn die Datenbank hakt.
8:21 Bei einer kurzen Datenbankstörung reißen Sie damit auch noch alle Anwendungsinstanzen um — aus einem Problem werden zwei. Die Datenbankprüfung gehört in die Bereitschaftsprüfung, nicht in die Lebendprüfung. Der erste Punkt ist derjenige, an dem Migrationen wirklich scheitern: Bei einem Rolling Update laufen zwei Versionen gleichzeitig — also muss das Datenmodell beide vertragen.
8:43 Wenn Ihre Migration eine Spalte umbenennt, sieht die alte Version sie nicht mehr, und für ein paar Minuten läuft die halbe Anwendung ins Leere. Deshalb gilt: Schemaänderungen immer in zwei Schritten, erst hinzufügen, dann nach dem Rollout entfernen. Und Punkt drei: Der Rückweg braucht ein altes Image, nicht einen neuen Build. Ein Rückweg, der einen Build voraussetzt, dauert im Ernstfall vierzig Minuten zu lang.
9:08 Der rote Faden ist: erst die Prüfpunkte, dann die Grenzen, dann das Verhalten unter Last, und ganz am Ende das Wichtigste — der Rückweg. Genau in dieser Reihenfolge, denn jeder Schritt setzt den vorigen voraus. Und beachten Sie die Fußzeile: Der geübte Rückweg ist wertvoller als das gelungene Update. Das gelungene Update erleben Sie oft; den Rückweg brauchen Sie selten, dann aber unter maximalem Druck.
9:32 Wer ihn einmal in Ruhe durchgespielt und die Dauer gemessen hat, kann im Ernstfall eine belastbare Aussage machen: Wir sind in vier Minuten zurück. Der erste Punkt ist der häufigste Konfigurationsfehler überhaupt: Lebendigkeit und Bereitschaft zeigen auf denselben Endpunkt. Damit verlieren Sie die Unterscheidung, die die Plattform braucht — und aus jeder vorübergehenden Störung wird ein Neustart.
9:55 Punkt zwei ist der klassische Speicherfehler: Ohne gesetzte Grenze belegt die JVM so viel, wie der Knoten hergibt, und reißt im Zweifel andere Anwendungen mit. Und Punkt vier ist die Wiederholung der wichtigsten Botschaft: Der Rückfall wurde nie geübt und dauert im Ernstfall Stunden. Üben Sie ihn einmal — an einem Dienstagvormittag, nicht am Freitagabend.
Übung
10:16 In der Übung bringen Sie Zählwerk in ein Image. Und Sie werden merken: Der Server ist nicht der schwierige Teil. Die eigentliche Arbeit steckt darin, Konfiguration und Zustand herauszulösen. Genau daran entscheidet sich, ob das Ergebnis wiederholbar ist. Sie bringen das bestehende WAR-Deployment mit einem provisionierten Server in ein Image, das ohne Eingriff in mehreren Umgebungen läuft.
10:40 Das Lernziel ist genau diese Unabhängigkeit: ein Artefakt, viele Umgebungen. Erfolgreich sind Sie, wenn dasselbe Image in zwei Umgebungen startet, alle umgebungsabhängigen Werte von außen kommen und die drei Prüfpunkte korrekt antworten. Als Vorlage dient das Inventar aus Modul zwei: Jede dort gefundene Serverressource muss hier einen Ort bekommen — im Image, in einer ConfigMap, in einem Secret oder auf der Streichliste.
11:05 Fünf Schritte, die genau der Reihenfolge des Moduls folgen: Server trimmen, Konfiguration herausziehen, Image bauen und in zwei Profilen starten, Prüfpunkte und Grenzen setzen, Rollout und Rückfall durchspielen. Der zweite Schritt ist der aufwendigste — dort sitzt die eigentliche Arbeit, und dort entscheidet sich, ob Sie ein Image gebaut haben oder nur einen Server in einen Container gestellt.
11:27 Und wie die Fußzeile sagt: Wer hier sauber arbeitet, hat den halben Weg zur Kubernetes-Übung in Modul vierzehn schon hinter sich. Die Fragen dort sind dieselben, nur für einen anderen Dienst. Punkt zwei ist der ehrlichste auf dieser Liste: Der Server bleibt vollständig, weil das Trimmen Zeit gekostet hätte. Das ist eine legitime Entscheidung — aber treffen Sie sie bewusst und schreiben Sie sie auf, statt sie passieren zu lassen.
11:51 Punkt drei ist ein feiner technischer Fehler mit großer Wirkung: Bereitschaft meldet bereit, bevor die Persistence Unit steht. Dann bekommt die Instanz Verkehr und beantwortet die ersten Anfragen mit Fehlern. Und Punkt vier hebt den ganzen Zweck auf: Wird das Image je Umgebung neu gebaut, ist es nicht mehr dasselbe Image — und Sie testen wieder etwas anderes, als Sie ausliefern.
Lieber mit Trainer? Dieses Modul ist Teil unserer Team-Schulungen — mit Übungen, Ihrem eigenen Code und Fragen, die ein Video nicht beantwortet. Mehr erfahren →