Wohl kaum ein Bereich des täglichen Lebens kommt in der Komplexität an die internationale Luftfahrt heran. Buchstäblich über die ganze Welt verteilt können hier bereits kleine Probleme große Auswirkungen haben, was dazu geführt hat, dass die Luftfahrt einen extrem hohen Anspruch an Sicherheit und Zuverlässigkeit entwickelt hat. Softwareentwicklung wird ebenfalls immer komplexer, dringt in immer neue Bereiche unseres Lebens ein und ihre Probleme haben zunehmend größere Auswirkungen. Es lohnt sich daher Dinge, die sich in der Luftfahrt bewährt haben, auch für uns als Entwickler zu analysieren und zu übernehmen. In einen zweiteiligen Artikel werden wir uns verschiedene Beispiele ein wenig näher anschauen.

Im ersten Teil werfen wir einen Blick auf diejenigen, die wir üblicherweise sofort mit der Luftfahrt verbinden: Die Piloten.

Dieser Artikel stammt aus dem Java Magazin 04.2024 und ist ebenfalls auf entwickler.de verfügbar.

Informationen zusammenführen

Mit dem Cockpit gibt es in jedem Flugzeug eine zentrale Stelle, an der alle Informationen aus dem uns über das Flugzeug zusammenlaufen. Mit einem Blick lassen sich für die Piloten so alle notwendigen Informationen schnell und einfach erfassen.

In der Softwareentwicklung haben wir ebenso eine ganze Reihe an unterschiedlichen Systemen und Tools, die uns Informationen über den Zustand unserer Anwendungen liefern. Um hier nicht immer wieder an verschiedenen Stellen, möglicherweise noch mit verschiedenen Zugangsdaten, Informationen abzurufen und manuell aggregieren zu müssen bieten sich auch für uns Werkzeuge an, die uns ein „Software-Cockpit“ bereitstellen. Log- und KPI-Aggregatoren sowie Dashboards helfen dabei uns nicht manuell durch unterschiedliche Frontends zu „wühlen“ sondern schnell und einfach Informationen auffinden zu können. Gerade, wenn es zu einem Ausfall kommt oder sich unsere Systeme nicht so verhalten, wie wir es erwarten, hilft es uns deutlich schneller zu erkennen, was gerade schiefläuft und – hoffentlich – schnell(er) eine Lösung zu finden.

Kontinuierlich Daten sammeln

Wir alle kennen es aus den Nachrichten – im traurigen Falle eines Flugzeugabsturzes ist eine der ersten Fragen typischerweise: Wie lange dauert es noch, bis der Flugschreiber gefunden wird? Die „Black Box“ zeichnet während eines Fluges kontinuierlich wichtige Daten wie Höhe, Geschwindigkeit und eine ganze Reihe an weiteren Parametern auf. So lässt sich im Katastrophenfalle besser herleiten, was genau passiert ist und welche Schlüsse für zukünftige Entwicklungen getroffen werden müssen.

In jüngerer Zeit werden auch regulär eine ganze Reihe an Daten vom Flugzeug an die Fluggesellschaft gesendet. So können Schwierigkeiten oder Abweichungen bereits frühzeitig erkannt und Reparaturmaßnahmen proaktiv eingeleitet werden noch bevor es zu einem Ausfall kommt, der eine aufwändige und teure Reparatur (oder schlimmeres) nach sich zieht.

Unsere Softwaresysteme fliegen jedoch nicht selten lediglich „auf Sicht“. Erst im Fehlerfalle beginnen wir mit der Analyse und versuchen herauszufinden, was genau passiert ist. Wie hilfreich ist es da auch für uns Informationen wie Speicher- oder Prozessorauslastung, über einen längeren Zeitraum analysieren zu können. So trifft uns ein Kapazitätsengpass nicht überraschend zu Spitzenzeiten, sondern kann bereits im Voraus erkannt und das System optimiert werden. Ähnliches gilt für Logging und Tracing: Wer von uns hat nicht schon vor einem Fehler gestanden und sich gewünscht nachvollziehen zu können, was ein Benutzer wohl genau gemacht und wo er geklickt hat um zu der beschriebenen Ausgabe gelangt zu sein. Auch hier hilft es uns bereits von Beginn an Informationen wegzuschreiben um sich im „Falle des Falles“ an den Brotkrumen entlang hangeln zu können. In Kombination mit einem Cockpit, in dem eben diese Daten visualisiert werden können erhalten wir so einen deutlich besseren Einblick in unsere Softwaresysteme.

Checklisten

Checklisten sind in der Luftfahrt allgegenwärtig. Ob vor dem Anlassen der Triebwerke, vor dem Start, nach der Landung oder verschiedenen anderen kritischen Zeitpunkten eines Fluges: Immer wird eine Checkliste zur Hilfe genommen, die den Piloten eine kurze Abfolge an Schritten vorgibt. Doch sollte man nicht meinen, dass einem Piloten, der seit Jahren (oder Jahrzehnten) ein Flugzeug fliegt, diese Schritte längst in Fleisch und Blut übergegangen sind und solche Checklisten daher längst überflüssig sind? Nein! Sie sind stattdessen ein weiterer Baustein in einer auf Sicherheit optimierten Industrie. Das Befolgen einer Checkliste gibt jedem ein zusätzliches Gefühl der Sicherheit, da nichts vergessen werden oder im Alltag untergehen kann. Es verhindert, dass durch Routine Fehler passieren, die (möglicherweise auch erst später) zu Problemen führen können.

Auch in unserer tagtäglichen Arbeit als Softwareentwickler gibt es immer wieder Dinge, die aus einer Reihe von sequenziellen Schritten bestehen, gleich ablaufen und dennoch (oder gerade deswegen) Raum für Fehler bieten. In einem meiner vergangenen Projekte bestand das Erstellen und Deployen eines Anwendungsreleases aus ca. 15 bis 20 verschiedenen Schritten, die für sich genommen alle relativ einfach und schnell durchgeführt waren, jedoch häufig auf eine genaue Ausführung der vorherigen Schritte angewiesen waren. Das Weglassen (oder die falsche Ausführung) eines einzelnen Schrittes konnte für den gesamten Releaseprozess am Ende schwere Folgen haben. Das Befolgen der Checkliste (und das bewusste Abhaken der einzelnen Schritte) jedoch gab jedem die Sicherheit an alles gedacht und nichts vergessen zu haben.

Ein weiterer großer Vorteil einer Checkliste im Softwareentwicklungsprozesses drängt sich geradezu auf: Die Automatisierbarkeit. Wenn es „nur“ noch Aufgabe eines Entwicklers ist die einzelnen Punkte der Checkliste nacheinander abzuarbeiten, so ist es nicht selten nur noch ein kleiner Schritt den Prozess zu Teilen oder sogar komplett zu automatisieren und die Ausführung einer Maschine zu übertragen, was uns als Entwicklern mehr Zeit gibt uns auf die Aufgaben zu konzentrieren, die eben nicht von einer Maschine durchgeführt werden können.

Plan B

Ein fester Teil der Vorbereitung eines jeden Fluges ist es für bestimmte Ausnahmesituationen bereits vor dem Start klare Alternativen zu besprechen und zu definieren. Fällt bei einem Start ein Triebwerk aus, so besteht keine Zeit erst dann über Alternativen nachzudenken. Stattdessen wird ein solcher „Plan B“ bereits im Vorfeld besprochen. Ebenso werden alternative Landeflughäfen für Szenarien wie schlechtes Wetter am Zielort festgelegt bevor die Piloten überhaupt an Bord des Flugzeuges gehen. Alles das dient dazu in kritischen Situationen schnell handeln zu können und keine wertvolle Zeit durch große Überlegungen oder Recherchen zu vergeuden.

Eine ähnliche Herangehensweise kann uns auch als Softwareentwickler mehr Sicherheit und weniger Stress einbringen. Auch wir können für kritische Situationen mögliche Fehlerquellen identifizieren und Lösungsstrategien zurechtlegen. Was passiert, wenn bei der Migration einer Datenbank der Switchover wider Erwarten doch nicht funktioniert? Was muss von wem getan werden, wenn bei einem Deployment der neuen Anwendungsversion plötzlich das System nicht mehr korrekt vom Loadbalancer erreicht werden kann? Es lohnt sich auch hier für typische Fehlerquellen alternative Lösungen „in der Hinterhand“ zu haben.

… und Plan C

In der Luftfahrt gibt es für besonders kritische Prozesse nicht nur einen Plan B sondern auch einen Plan C, der berücksichtigt was zu tun ist, wenn selbst der Plan B nicht funktioniert bzw. ergänzt werden muss. Redundanz über Redundanz. Ein sehr plakatives Beispiel hierfür ist die Tatsache, dass auf Transatlantikflügen eine bestimmte Anzahl an Polarjacken im Flugzeug mitgeführt werden muss. Im Falle einer Ausweichlandung in Grönland oder Nordkanada auf einem abgelegenen Flughafen ist unter Umständen kein oder nur wenig Bodenpersonal verfügbar, sodass einer der Piloten sich persönlich außerhalb des Flugzeuges vom Zustand bestimmter Komponenten (z.B. des Triebwerks) überzeugen muss – und im grönländischen Winter möchte man dies nicht ohne entsprechende Kleidung tun.

Im Softwareumfeld können wir uns ähnliche Szenarien vorstellen. Ein Backup der Daten als Plan B ist glücklicherweise in dem meisten Softwaresystemen inzwischen Standard. Doch ist es ausreichend das Backup beim gleichen Cloudanbieter zu hosten, wo die eigentliche Anwendung betrieben wird? Nein. Mein Worst-Case-Szenario ist nicht, dass AWS, Google oder Microsoft meine Daten verlieren, sondern, dass ich versehentlich vergesse meine Verträge zu verlängern und deshalb das Backup-Bucket automatisch gelöscht wird. Und selbst exotische Szenarien treten irgendwann ein: Auch Rechenzentrum brennen ab und an im wahrsten Sinne des Wortes ab.

Eine mögliche Lösung, die hier mehr Sicherheit bietet ist ein von Anfang an aufgesetztes Backup, dass (zusätzlich) die Daten in ein Ziel bei einem anderen Cloudanbieter, einer anderen Region oder im guten alten Datenschrank vor Ort speichert.

Regelmäßiges Training

Der beste Plan B bringt nichts, wenn er im Falle des Falles nicht korrekt angewendet werden kann. Wirkliche Notfälle sind in der Luftfahrt heutzutage Gott sei Dank extrem selten geworden – sie bleibt die sicherste Art von A nach B zu gelangen. Dennoch besteht der überwiegende Teil des Trainings von Piloten (und vielen anderen in der Luftfahrt Beschäftigten) in der Simulation von Not- und Problemfällen – möglichst realitätsnah. Nur wer als Pilot tatsächlich einmal erlebt hat, wie sich ein Triebwerksausfall anfühlt, der wird auch in der Realität schnell auf die erlernten Problemlösungsstrategien zurückgreifen können.

Nichts anderes gilt auch für uns als Softwareentwickler. Was hilft das beste Backup, wenn niemand in der Lage ist die Daten auch tatsächlich wieder so einzuspielen, dass unsere Systeme wieder benutzbar sind? Im besten Falle dauert die Wiederherstellung einfach nur sehr lange, weil verschiedene Wege ausprobiert werden müssen, bis der korrekte gefunden wurde. Im schlimmsten Falle sind die Daten zwar vorhanden, lassen sich aber schlicht und ergreifend nicht mehr in die bestehenden Systeme integrieren. Es lohnt sich daher auch für uns kritische Reparaturmaßnahmen zu simulieren und (regelmäßig) zu trainieren.

Ein Beispiel, dass ich selbst vor einigen Jahren sehr erfolgreich im Team umgesetzt habe war das Simulieren eines Datenbankkomplettausfalls und das Wiederherstellen der Datenbankinstanz sowie das Einspielen der Backupdaten. Zwei unserer Entwickler wurden per Zufallsgenerator ausgewählt und erhielten ein Simulationsszenario: Eine unserer Datenbanken (auf dem Stagingsystem) war nicht länger funktionsfähig und die beiden Entwickler waren die einzigen, die die entsprechenden Zugänge hatten, um eine Wiederherstellung einzuleiten.

Auch wenn jedem bewusst war, dass es sich „nur“ um das Stagingsystem handelte und keine realen Kundendaten betroffen waren, erfüllte die Übung dennoch ihren Zweck. Unsere Prozesse und Anleitungen, wie eine Wiederherstellung erfolgen konnte, wurden mit jeder neuen Übung besser und die Kollegen verloren ihren Respekt (vielleicht sogar ihre Angst) vor einem echten Ausfall. Sie wussten, wie man dieses Problem beheben konnte, da sie es bereits „live und in Farbe“ durchgeführt hatten. Ein echter Datenbankausfall blieb uns glücklicherweise bisher erspart, aber unser gesamtes Team hätte einen solchen Fall – dank des guten Trainings – kompetent lösen können.

Don’t panic

Es war sicherlich der Albtraum eines jeden Piloten. Kurz nach dem Start von US Airways Flug 1549 am 15. Januar 2009 fielen durch einen Vogelschlag beide Triebwerke des Airbus A320 aus und dem Piloten Chesley Sullenberger bliebt nichts andere übrig als eine Notwasserung im Hudson River durchzuführen. Die Bilder des Flugzeuges nach der erfolgreichen Landung gingen um die Welt und sind uns auch durch die Verfilmung mit Tom Hanks im Gedächtnis geblieben.

Wenn man sich den Funkverkehr anhört, so erkennt man die geradezu stoische Ruhe des Piloten und auch in Interviews erklärte Sullenberger, dass er zu keinem Zeitpunkt in Panik verfallen war, sondern routiniert seine geübten Notfallpläne angewendet hat. Alle Experten sind sich einig, dass gerade diese Ruhe eine der Hauptgründe dafür war, dass die Maschine trotz enormer Schwierigkeiten erfolgreich gelandet werden konnte.

Wie unterschiedliche verlief da manches Problem, dass ich als Softwareentwickler erlebt habe. Sobald sich unsere Systeme anders verhalten, als wir uns das vorstellen verfallen wir häufig in Aktionismus und versuchen irgendetwas zu tun in der Hoffnung, dass es die Lösung bringen wird.

Ein arabisches Sprichwort sagt, dass Panik aus einer Mücke einen Elefanten macht und Geduld aus einem Elefanten eine Mücke. Eine Situation, die mir selbst gezeigt hat, wie kontraproduktive übereiltes Handeln sein kann ist nur wenige Jahre her. Einer unserer Services reagierte nicht mehr, was dazu führte, dass bestimmte Teile der UI vom Benutzer nicht mehr verwendet werden konnten. In Aufregung (vielleicht sogar Panik) aber mit der Intention schnell Abhilfe zu schaffen wählte ich – ohne tiefer auf das Problem zu schauen – eine Aktion, die schon häufiger zum Erfolg geführt hatte: Einen Neustart des entsprechenden Services. Das Problem wurde dadurch allerdings nicht besser, sondern im Gegenteil, nur noch schlimmer. Es stellte sich später heraus, dass die Ursache in der Drosselung der Datenbankzugriffe durch den Datenbankserver aufgrund von aufgebrauchten IO-Credits lag. Durch den Neustart des Services hatte sich diese Situation nur noch verschlimmert, da zunächst verschiedenste Konfigurationsdaten ausgelesen und Caches initialisiert werden mussten. Es fanden daher nur noch mehr Datenbankabfragen statt, die die Last zusätzlich erhöhten. Ich hatte das Problem durch voreiliges Handeln nur verschlimmert anstatt es zu lösen.

Auch wenn es im ersten Moment widersprüchlich zu sein scheint: In einer Ausnahmesituation ist ein tiefes Durchatmen und ein ruhiges Analysieren der Situation der beste Weg zu einer Lösung zu gelangen. Es gilt zuerst zu verstehen, was überhaupt passiert ist und wo das Problem liegt. Erst dann sollten wir in den Lösungsmodus übergehen.

Fazit

Ein Blick auf die Luftfahrt zeigt uns eine ganze Reihe an Prozessen aber auch an Selbstverständlichkeiten, die uns als Softwareentwickler dabei helfen können unser Handwerk noch besser ausführen zu können. Die hier vorgestellten Beispiele können sowohl einzeln eingesetzt werden aber entfalten besonders im Zusammenspiel ihre ganze Kraft. Checklisten sind für sich bereits ein gutes Mittel um Fehler zu reduzieren aber in Zusammenhang mit regelmäßigem Training von Situationen, die sie verwenden, ergeben sich weitere Synergieeffekte. Gutes Training hilft ebenso dabei zu lernen, wie man in solchen Situationen Ruhe bewahren und sich die Lösung fokussieren kann ohne in Panik zu verfallen.

Ausblick

Im nächsten Teil werden wir uns noch eine zweite Kategorie von Personen in der Luftfahrt anschauen – den Flugzeugmechaniker – und erkennen (hoffentlich), dass wir auch hier eine Menge lernen können.

Diese Themen könnten Dich auch interessieren

Symbolbild für Domainlifecycles Code Generator (DCG)

Ein Generativer KI-Assistent für Domain-Driven Design

Hier erfährst Du, wie der KI-Assistent für Domain-Driven Design „Domainlifecycles Code Generator“ funktioniert und entwickelt wurde.
Schmuckbild zum Thema Chatbot Assistenten durch Nutzung von LLMs und Retrieval Augmented Generation

Chatbot Assistenten durch Nutzung von LLMs und Retrieval Augmented Generation

Wir erläutern die Architektur eines Chatbots, der durch die Nutzung von LLMs und Retrieval Augmented Generation schnell und effizient auf Fragen antwortet.
Eine Person analysiert eine Datenauswertung auf dem Bildschirm eines MacBooks.

Revolution in Real-time Analytics: Wie Tiered Storage Dateneffizienz transformiert

Wir zeigen Dir, welche Auswirkungen Speicherstrategien in Bezug auf Real-time Analytics haben.

Nimm gerne Kontakt zu uns auf!

Du hast noch Fragen und/oder Ideen? Du kennst noch andere Branchen, aus denen wir Inspiration gewinnen können? Dann freue ich mich auf den Austausch mit Dir!

Sende mir gerne eine Mail, vernetze Dich mit mir oder hinterlasse Deine Kontaktdaten.

Christian Seifert, Principal Consultant Geschäftskreis Architektur, esentri AG

Christian Seifert
Principal Consultant
Geschäftskreis Architektur