© Excellent backgrounds/Shutterstock.com
Resilient Software Design

Ein Jahr später ...


Vor gut einem Jahr gab es einen Schwerpunkt Resilience im Java Magazin. Dazu gehörte unter anderem ein Artikel von mir, der in das Themengebiet eingeführt hat. Ein gutes Jahr später stellt sich die Frage, was sich seitdem getan hat. Wie hat sich das Thema im Markt entwickelt? Gibt es neue Erkenntnisse? Was fehlt immer noch? Zeit für eine kleine Bestandsaufnahme und ein paar Ergänzungen.

Für alle, die meine Einführung in Ausgabe 5.2015 [1] nicht gelesen haben, zum Einstieg eine ganz kurze Erläuterung, worum es bei Resilient Software Design überhaupt geht: Resilient Software Design lässt sich semi-formal als die Gestaltung und Umsetzung einer softwarebasierten Lösung definieren auf eine Weise, dass der Nutzer bei einer unerwarteten Fehlersituation davon im besten Fall überhaupt nichts bemerkt, und anderenfalls die Lösung in einem definierten, reduzierten Servicelevel weiterarbeitet.

Wichtig ist bei dieser Definition, dass die Lösung mit unerwarteten Fehlersituationen umgehen können muss. In den heutigen verteilten, hochgradig vernetzten Softwarelandschaften ist es nicht mehr möglich, a priori alle möglichen Fehlersituationen vorherzusehen und durch entsprechende Maßnahmen zu vermeiden. Insbesondere kann man sich nicht auf das korrekte Funktionieren von Bausteinen außerhalb des eigenen Prozesskontexts verlassen, sondern muss zu jeder Zeit davon ausgehen, dass sie nicht, nur sporadisch, zu langsam oder falsch reagieren. Tatsächlich kann man sich auch nicht auf das ordnungsgemäße Funktionieren des eigenen Prozesskontexts verlassen. Denn innerhalb eines Prozesses hängt man in der Regel an dem gleichen Lebensfaden wie der aufgerufene Baustein. Stirbt der aufgerufene Baustein oder wird langsamer, geht es einem als Aufrufer genauso. Aufgrund dieser Sondersituation kann man sich im Code deshalb entsprechende Fehlerbehandlungen sparen. Arbeitet man innerhalb eines Prozesses allerdings mit mehreren ­Threads – was heutzutage häufig der Fall ist –, hat man mit gewissen Einschränkungen die gleichen Probleme wie bei der Nutzung von Bausteinen über Prozessgrenzen hinweg.

Der zweite wichtige Punkt bei dieser Definition ist das Zurückfallen auf einen definierten Servicelevel, falls man nicht in der Lage ist, einen Fehler so zu kompensieren, dass der Nutzer gar nichts davon merkt. Das Schlüsselwort ist „definiert“. Häufig erlebt man Anwendungen, bei denen im Fehlerfall ein eher zufälliges Verhalten zu beobachten ist, das auf Systemdefaults, gepaart mit der vom Entwickler für die Fehlerbehandlung eher zufällig gewählten Implementierung, basiert. Ein solches Verhalten ist nicht zulässig. Der Nutzer muss stets ein klar definiertes, a priori festgelegtes Verhalten gezeigt bekommen.

Der 100-Prozent-Verfügbarkeit-Irrtum

Das bedeutet im Umkehrschluss, dass das Verhalten des Systems bei technischen Fehlern Teil der fachlichen Systemspezifikation wird. Es muss sich also der Product Owner, der Requirements Engineer, oder wer auch immer das fachliche Verhalten des Systems definiert, Gedanken darüber machen, wie das System bei technischen Fehlern reagieren soll. Kann man im Fehlerfall mit geeigneten fachlichen Defaults weiterarbeiten? Soll eine Fehlerseite angezeigt werden? Oder sind aus fachlicher Sicht weiterreichende Maßnahmen zum Umgang mit der Fehlersituation erforderlich? Dies passiert aber bis heute nur sehr selten. Tatsächlich wird implizit von einer hundertprozentigen Verfügbarkeit der beteiligten Bausteine ausgegangen. Die irrige Idee: Jeder Baustein stellt für sich sicher, dass er maximal verfügbar ist. Dann ist garantiert, dass eine Nutzung des Bausteins erfolgreich ist. Diese Annahme ist hinreichend, wenn eine Anwendung ohne oder mit nur sehr wenig Remote-Kommunikation ihre Leistung erbringen kann. Aber alle Systeme, bei denen eine hohe Verfügbarkeit wichtig ist, bestehen heute in der Regel schon aus mehreren Tiers, wie Webserver, Application Server, Datenbank, diverse Caching-Layer, Proxyserver etc. Zusätzlich nutzen sie häufig Dutzende andere Systeme, um ihre Dienstleistung zu erbringen.

Gehen wir pro benötigtem Baustein von einer Verfügbarkeit von 99,5 Prozent inklusive geplanter Downtimes aus. Und das ist ein ziemlich hoher Wert. Nur wenige Softwarebetreiber sind bereit, so hohe Verfügbarkeiten in ihren SLAs zu garantieren. Bei zehn beteiligten Bausteinen sind wir dann bei einer Gesamtverfügbarkeit von ca. 95 Prozent und bei fünfzig beteiligten Bausteinen – heute keine Seltenheit bei wichtigen Unternehmensanwendungen – bei einer Gesamtverfügbarkeit von ca. 75 Prozent. Dabei sind noch nicht die Ausfälle der Netzwerkinfrastruktur mit eingerechnet, die ebenfalls wesentlich häufiger auftreten, als man üblicherweise annimmt. Für eine Übersicht siehe z. B. Kapitel 2 in [2]. Entsprechend liegt die Gesamtverfügbarkeit des Systems noch unter den genannten Zahlen. Und berücksichtigt man aktuelle Trends wie Microservices, Self-contained Systems, Cloud-Infrastrukturen, Mobile First und das aufkeimende Internet of Things, wird ganz schnell klar, dass die Anzahl der Bausteine eher noch wachsen wird.

Kurzum: Die hundertprozentige Verfügbarkeitsannahme genutzter Bausteine ist keine Option. Trotzdem trifft man sie noch allenthalben an. Das beginnt bei Fach­experten, die versuchen, sich mit Kommentaren wie „Das ist die Verantwortung von euch IT-lern, dafür zu sorgen, dass das nicht passiert“ um das Thema zu drücken, und geht bis zu Entwicklern, von denen man hört „Ach was, das ist doch ein Cluster und so hoch verfügbar, da muss ich die Zugriffe nicht absichern“. Das habe ich noch vor wenigen Wochen in einem Projekt fast im Wortlaut zu hö...

Neugierig geworden?

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang