Podcast

Resilienz

Prozesse, Kultur und Technik

Wie entstehen resiliente Systeme – und welche Rolle spielen dabei Qualitätsziele, Teamstrukturen und Lernkultur? In dieser Folge des INNOQ Podcasts sprechen Anja Kammer und Kofi Jedamzik über Resilienz auf verschiedenen Ebenen. Von der Frage, welche Systeme überhaupt resilient sein müssen, über den Umgang mit unbekannten Fehlerszenarien bis zur Balance zwischen Innovation und Stabilität.
Weitere Episoden anhören

Shownotes & Links

📹 Hinweis: Diese Podcast-Folge ist auch als Video auf YouTube verfügbar.

Transkript

Transkript ausklappen / einklappen

Dieses Transkript wurde automatisiert erstellt und nicht manuell überprüft. Es kann daher Fehler enthalten. Massgeblich ist immer das im Mitschnitt gesprochene Wort.

Anja Kammer: Hallo und herzlich willkommen zum INNOQ Podcast. Mein Name ist Anja Kammer und heute zu Gast habe ich Theo Pack. Hallo Theo.

Kofi Jedamzik: Hallo, schön hier zu sein.

Anja Kammer: Heute reden wir über Resilienz. Es geht darum, wie ein System resilient sein sollte oder ob es überhaupt resilient sein soll und wie resilient ein System sein muss. Auch, dass es eine Chance sein kann, wenn es nicht resilient ist, um später das System zu verbessern und resilienter zu werden. Wir werden auch darüber sprechen, dass es nicht nur um technische Maßnahmen geht, sondern auch um Menschen, Prozesse und sogar Kultur. Darauf freue ich mich. Dann fangen wir doch gleich mal mit der Definition an, was Resilienz überhaupt ist, damit wir alle wissen, worum es geht.

Kofi Jedamzik: Genau. Resilienz ist im Prinzip die Eigenschaft eines Systems, trotz eines Fehlers, der von außen eintrifft, durch unerwartete Eingaben vom Nutzer oder durch äußere Bedingungen, trotzdem eine nützliche Funktionalität dem Nutzer bereitstellen zu können. Das heißt, es geht im Zweifelsfall gar nicht darum, dass ein System dann noch läuft, sondern dass es grundsätzlich in der Lage ist, eine Funktionalität bereitzustellen und nützlich zu sein. Das ist im Prinzip der Kern.

Anja Kammer: Das heißt, ein System läuft, bedeutet, der Server ist erreichbar, aber Nützlichkeit ist ja definiert dadurch, was der Nutzende für nützlich empfindet.

Kofi Jedamzik: Genau. Das hängt natürlich immer vom System ab und auch von der Person, die vor dem Rechner sitzt. Als Beispiel kann ein System verfügbar und erreichbar sein, aber es kann so langsam sein, dass Nutzer es nicht als nützlich oder nutzbar empfinden. So ist er dann auch nicht mehr in der Lage, die Funktionalität oder die Anwendung so zu benutzen, wie er es in dem Moment benötigt.

Anja Kammer: Als Beispiel ein Social Media Netzwerk wie Instagram oder Ähnliches, wo es sich um Bilder und Videos handelt, die gezeigt werden. Das Anzeigen von Bildern und Videos wäre sehr wichtig und kritisch für das System, aber das Hochladen nicht so wirklich, weil das soziale Medium trotzdem noch nutzbar ist, ohne dass man neue Medien hochladen kann. Das bedeutet, wenn die Daten sichtbar sind, ist das System noch verfügbar und nützlich und resilient gegenüber Fehlern. Der Fehler wäre, dass keine Bilder und Videos mehr hochgeladen werden könnten, aber das System funktioniert trotzdem noch.

Kofi Jedamzik: Genau. Da geht es schon ein bisschen in die Richtung, was kann ich alles tun, welche Strategien kann ich anwenden, um beispielsweise Teilfunktionalitäten noch bereitstellen zu können, sodass ich die Anwendung vielleicht nicht als Ganzes nutzen kann, aber zumindest Teile und damit dann auch das erfüllen kann, was für die breite Masse der Nutzer oder für die wichtigen Nutzer dann noch wichtig ist.

Anja Kammer: Genau. Und wenn es jetzt andersherum wäre, wenn zum Beispiel die Bilder nicht mehr angezeigt werden würden, dann wäre es ein Ausfall, obwohl die Server noch laufen, aber das Hauptfeature ist nicht mehr da. Wäre es dann ein Ausfall, oder?

Kofi Jedamzik: Man könnte es als Ausfall bezeichnen. Das ist ja im Prinzip dann auch das, was die Leute draußen als Ausfall bezeichnen würden. Dass sie sich über andere Social Media Plattformen beschweren, dass Plattform X gerade down ist oder sich nicht benutzen lässt, obwohl vielleicht die Server noch laufen und obwohl vielleicht zum Teil noch Bilder geladen werden können, aber in so einer Geschwindigkeit, dass es für den Nutzer im Prinzip ein Ausfall darstellt.

Anja Kammer: Ja, das finde ich sehr wichtig. Wenn man über Resilienz redet, redet man auch gleichzeitig immer über Verfügbarkeit und dann sagt man, wie viel Neunen habt ihr, habt ihr Five Nines oder Ähnliches. Ich frage mich dann immer, auf was bezieht ihr denn eure Five Nines der Verfügbarkeit? Und wie du gerade gesagt hast, es kommt auf die Nutzenden an oder wer definiert das, der PO vielleicht.

Kofi Jedamzik: Genau.

Anja Kammer: Ich hatte ja schon gesagt, wie resilient soll denn jetzt unser System eigentlich sein? Muss es die berühmten Five Nines der Verfügbarkeit haben, das heißt eine sehr hohe Resilienz und dementsprechend auch eine hohe Verfügbarkeit, oder brauche ich Resilienz überhaupt? Brauche ich immer Resilienz? Wie wichtig ist das überhaupt?

Kofi Jedamzik: Typische Beraterantwort in dem Kontext: Es hängt davon ab, in welchem Kontext ich mich befinde, wie meine Anforderungen aussehen. Grundsätzlich würde ich das davon abhängig machen, was meine Qualitätsmerkmale an mein Gesamtsystem betrifft und davon ableiten, entsprechende Maßnahmen auf verschiedenen Ebenen zu treffen, um diese Resilienz sicherstellen zu können.

Anja Kammer: Also das bedeutet, anhand von Qualitätsmerkmalen setze ich mir Qualitätsziele und anhand der Ziele, die von irgendjemandem, vom Management, von Architektinnen gesetzt wurden, sehen wir dann, wie hoch die Priorität für Resilienz ist. Und wenn ich über Qualitätsziele nachdenke und wie man sie definiert, dann weiß ich auch, dass ich Qualitätsszenarien beschreiben sollte. Das heißt, Szenarien, die beschreiben, wie die Qualität sichtbar wird. Und dann würde ich doch eigentlich auch Ausfallszenarien beschreiben, die dann die Resilienz beschreiben, die ich haben möchte.

Kofi Jedamzik: In der Regel, so wie ich sie beschreiben würde, wird es dann wahrscheinlich doch am Ende des Tages in der Kategorie Verfügbarkeit verortet werden. Das heißt, ich möchte ja meinem Nutzer für eine gewisse Zeit oder mein Nutzer für eine prozedurale Zeit über eine gesamte Zeitlänge das System zur Verfügung stellen. Das würde ich schon unter dem Begriff Verfügbarkeit sehen. Als Beispiel: , % des Monats soll der Nutzer in der Lage sein, seine Anwendung nutzen zu können. Das heißt, unter diesem Aspekt würde ich beispielsweise genau diese Fähigkeit sehen. Ich würde es aber auch in anderen Aspekten sehen. Es ist ja nicht nur die Fähigkeit des Systems, grundsätzlich diese Funktionalität zur Verfügung zu stellen, sondern ich muss mir ja auch darüber Gedanken machen, was passiert in bestimmten Szenarien, und da kommen ja auch andere Eigenschaften zum Tragen, wie beispielsweise, dass ich in der Lage bin, ein System wiederherstellen zu können.

Und das kann sich dann natürlich auch in anderen Szenarien widerspiegeln. Ich habe, glaube ich, zumindest in meinen vergangenen Projekten kein Szenario gesehen, was konkret auf diese Resilienz abzielt, sondern sie war mehr Teil von anderen Qualitätsszenarien, die dann unter einem anderen Titel laufen. Das Gleiche gilt auch beispielsweise, und das zählt ja auch unter Resilienz, dass ein System gewisse Sicherheitsmerkmale aufweisen muss. Es muss robust oder resilient gegen bewusste Angreifer sein. Diese Szenarien würde ich dann auch eher unter den ganzen Security-Aspekten sehen und davon ableitend dann entsprechende Eigenschaften bezüglich Resilienz und dann entsprechend den Strategien, die ich dafür nutzen würde, verorten.

Anja Kammer: Das bedeutet aber auch, ganz normale Architekturarbeit führt dazu, dass unsere Systeme resilienter werden, und das ist sozusagen die Grundlage dazu. Erstmal die Qualitätsmerkmale beziehungsweise Qualitätsziele setzen, Qualitätsszenarien schreiben und dann schauen, wie resilient sollte mein System denn sein gegenüber welchen Szenarien, und dann erst leite ich Maßnahmen für mein System ab.

Kofi Jedamzik: Genau.

Anja Kammer: Zumindest, wenn wir den, ich nenne es mal, den technischen Teil uns anschauen. Du hattest ja auch anfangs schon gesagt, wir haben noch einen anderen Teil, wo es um Prozesse und Kultur grundsätzlich geht.

Kofi Jedamzik: Die lassen sich natürlich dann schwieriger aus diesen Szenarien herauslesen, sondern mehr aus einer Resilienz für das gesamte Unternehmen oder die gesamte Plattform und nicht nur Teilsysteme.

Anja Kammer: Dann lass uns doch darüber sprechen, was das für organisatorische und kulturelle Maßnahmen für Resilienz sind. Mir fällt auf jeden Fall so etwas wie Postmortems ein. Wenn es einen Incident gab und wir daraus lernen, es hat irgendetwas nicht funktioniert, was muss ich tun, welche Maßnahmen muss ich ergreifen, damit das nicht noch mal auftaucht? Dann haben wir so etwas wie Postmortems. Das bedeutet, alle, die daran beteiligt waren oder die Systeme warten, die zu einem Ausfall führten oder wo es einen Incident gab, die setzen sich zusammen und rekonstruieren den ganzen Incident und schreiben auf, wie der Ablauf war, was dazu geführt hat und welche Maßnahmen ergriffen werden sollten. Das fällt mir ein, wenn wir jetzt über organisatorische Maßnahmen sprechen. Was gibt es denn noch?

Kofi Jedamzik: Genau, also einmal die organisatorischen, wobei ich das auch zur Kultur zählen würde. Grundsätzlich, dass ich akzeptiere, dass es Fehler gibt, dass ich Fehler auch gar nicht beim Menschen an sich suche, sondern dass es eigentlich ein systematisches Problem darstellt. Dass ich auch weniger mit Fingern auf andere zeige, sondern dass man eher das Positive darin sieht und die Chance daraus zu lernen und zu nutzen und in Zukunft dann resilienter zu sein, sowohl das System als auch vielleicht in der Organisation. Es gibt, das zählt auch wieder ein bisschen Richtung Kultur, ich kann natürlich auch dafür sorgen, dass ich beispielsweise solche Themen wie Resilienz oder Ähnliches dem gesamten Team als Verantwortung übergebe, dass ein gesamtes Team dafür verantwortlich ist und nicht nur einzelne Personen. Das sorgt natürlich auch dafür, dass wenn die Einzelperson mal, warum auch immer, das Unternehmen verlassen sollte oder nicht verfügbar ist, weil sie krank ist oder im Urlaub ist, dass bei einem Ausfall oder beim Incident dann trotzdem das gesamte Team in der Lage ist, diesen Incident zu beheben. Das würde ich auch im Prinzip zu einem Aspekt sehen, dass ich kulturell etwas anpassen kann.

Anja Kammer: Ja, finde ich aber sehr wichtig, vor allem, weil ich das so selten in der Praxis sehe. In der Praxis sehe ich, dass es oft irgendwie einen DevOps Champion gibt, einen Resilience Champion oder so, und die müssen sich darum kümmern, und alle anderen sprechen sich da frei: 'Damit habe ich nichts zu tun, das muss derjenige machen.’ Ist aber ein bisschen blöd, wenn es zu einem Incident kommt und genau diese Person nicht da ist, Urlaub hat oder Ähnliches. Es wäre schon gut, wenn eben das gesamte Team sich dann darum kümmern kann. Siehst du das als Anti-Pattern, so einen Resilience Champion oder DevOps Champion im Team zu haben?

Kofi Jedamzik: Langfristig, zumindest wenn es so gelebt wird, dass eine Person dafür verantwortlich ist, das gesamte Resilienz-Thema zu verantworten und der Rest des Teams damit nichts zu tun haben möchte und dann auch nicht in der Lage ist, vor allem langfristig. Kurzfristig oder mittelfristig kann es natürlich ein Weg sein, dieses Know-how in diese Teams reinzubringen. Dort einen Champion zu etablieren, der dazu da ist, Wissen zu verteilen. Und aus meiner Sicht spricht auch nichts dagegen, einen Champion zu haben, der dieses Wissen fokussiert hat, was sein Spezialgebiet ist. Was langfristig nicht passieren darf, ist, dass sich die anderen Teammitglieder für dieses Thema gar nicht verantwortlich fühlen.

Anja Kammer: Was wir jetzt ein bisschen unterschlagen haben, ist, dass es ja schon Strukturen für Resilienz gibt. Es gibt oftmals auch SRE-Teams, also Site Reliability Engineering Teams, das ist etwas übergeordnetes für die gesamte IT-Organisation. Wie ordnest du das dort in dieses Bild ein?

Kofi Jedamzik: Was bei den organisatorischen und kulturellen Aspekten auch noch wichtig ist: Du hast die Postmortems angesprochen. Wichtig ist auch, dass man die Postmortems durchführt, dort entsprechend lernt und das Wissen teilt. Das heißt, dass ich das dokumentiere und idealerweise auch anderen Teams zur Verfügung stelle. Das Gleiche gilt dann auch für die SRE-Teams, dass die als Knowledge Hub dienen können, um solche Themen zu koordinieren und bestimmte Findings aus vergangenen Incidents den Teams zur Verfügung stellen zu können, in welcher Form auch immer. Das kann über Dokumentation, Vorträge oder Ähnliches passieren. Sie können als Knowledge Hub und Expertenteam innerhalb der Unternehmen auftreten.

Anja Kammer: Ja, das klingt gut. Ich habe auch schon gesehen, dass Postmortems irgendwo verschwinden. Sie werden zwar angefertigt, aber sie verschwinden dann in irgendeiner Schublade und keiner sucht danach oder versucht daraus zu lernen. Deswegen finde ich es eine sehr gute Idee, das als Vorträge zu gestalten, wie du gesagt hast, dass man interne Konferenzen veranstaltet, wo die Leute, die direkt beim Incident dabei waren oder einen Incident hervorgerufen haben, erzählen, wie sie das Gesamtsystem für zwei Stunden lahmgelegt haben und ihre Geschichte erzählen. Das kann sehr lustig und gut sein, damit die Leute sich daran erinnern: Was war das Problem, wie haben wir es gelöst? Wenn es in einem Repository dokumentiert ist und keiner es sich ansieht, kann keiner daraus lernen. Es muss Interaktivität und Menschlichkeit dabei sein.

Kofi Jedamzik: Das hilft.

Anja Kammer: Gut, jetzt sind wir schon bei den Maßnahmen. Ich wollte noch weiter über Resilienz sprechen, was resiliente Systeme überhaupt ausmacht, welche Eigenschaften resiliente Systeme haben. Wie kann ich mir das vorstellen? Was ist ein resilientes System? Ich kann mir vorstellen, dass ein resilientes System sich neu starten kann, ohne dass es lange dauert, Daten zu kopieren oder korrupte Daten beim Neustart hinterlässt. Das ist das erste, was mir einfällt. Was gibt es noch für Eigenschaften für resiliente Systeme?

Kofi Jedamzik: Es gibt ein Paper von David Woods, das können wir sicherlich irgendwo verlinken. Er hat vier Eigenschaften beschrieben, die aus seinen Beobachtungen resiliente Systeme ausmachen. Er beginnt mit der Robustheit eines Systems. Dabei geht es um Situationen, die ich erwarten kann und auf die ich mich vorbereiten kann. Das ist eine Eigenschaft, und ein Beispiel wäre, wenn ich mein System redundant aufstelle. Dann gehe ich von der Situation aus, dass mal, warum auch immer, ein Server ausfallen kann, dann ist der zweite noch da, um die Anfragen an das System bearbeiten zu können. Also, einmal Robustheit: sich auf Szenarien vorzubereiten, die mir bekannt sind. Dann die Eigenschaft Rebound: Wie kann sich mein System erholen? Ein einfaches Beispiel ist, dass ich mir Gedanken über Backup-Strategien, Rollback-Strategien mache, wenn ich deploye, und dann in der Lage bin, ältere Versionen wieder einspielen zu können. Das heißt, ich bin in der Lage, mich von bekannten Situationen, die eintreten können, wieder erholen zu können. Dann geht es um die Eigenschaft, wie ich mit Situationen umgehe, die mir nicht bekannt sind, also mit unbekannten Situationen. Wo ich im Zweifelsfall kreative Lösungen brauche, weil ich mich plötzlich in einem unbekannten Szenario befinde.

Anja Kammer: Was ist kreativ? Welche Maßnahmen können kreativ sein?

Kofi Jedamzik: Es gibt häufiger Problemfälle, die auf Anhieb nicht direkt bekannt sind. Ich habe ein Problem und kann nicht direkt sehen, wo es eigentlich liegt. Das heißt, ich muss in der Lage sein – wenn meine Systeme das nicht aufdecken können, dann in der Regel mein Team – am Ende des Tages sind es wahrscheinlich die Menschen, die einen Blick darauf werfen und das Problem identifizieren müssen. Da muss ich im Zweifelsfall kreativ sein im Sinne von: Welche Informationsquellen kann ich mir jetzt anzapfen? Weil ich im Zweifelsfall noch nicht einmal wirklich verorten kann, wo das Problem gerade auftritt.

Anja Kammer: Das heißt, wir brauchen ein gutes Monitoring-System, gute Observability, damit bei einem Incident kreativ nach Lösungen gesucht werden kann. Es geht also nicht um Automatisierung, um das abzufangen, sondern es passiert etwas, und wir brauchen Observability, um herauszufinden, was die Menschen jetzt tun.

Kofi Jedamzik: Observability ist ein technisches Hilfsmittel dafür. Am Ende des Tages geht es viel wichtiger um die Eigenschaft, diese Flexibilität zu haben, um das Problem zu identifizieren, aber dann auch die in Anführungszeichen Kreativität und Flexibilität, um Lösungen dazu zu finden. Es hilft mir im Zweifelsfall nicht, das Problem zu identifizieren, sondern ich muss den zweiten Schritt gehen und eine Lösung finden, an die ich vorher nicht gedacht habe. Das ist genau der schwierige Teil. Alles, was ich wegautomatisieren kann, würde ich unter den ersten beiden Eigenschaften sehen: sich auf Szenarien vorbereiten, die mir bekannt sind, wie das mit der Redundanz, wenn Server ausfallen, oder Szenarien, wo Teile komplett wegbrechen, wo ich Backups einspielen oder Disaster-Recovery-Prozesse anlaufen lassen muss. Aber hier geht es wirklich um Situationen, die mir komplett unbekannt sind, und das Team dann in der Lage sein muss, das Problem zu identifizieren und eine entsprechende Lösung zu finden. Und was dort hilfreich ist, sind Teamstrukturen oder Organisationsstrukturen, wo vor allem die Teams Entscheidungsspielräume haben. Wo sie nicht erst bei einer zentralen Stelle Bestätigung oder Informationen einholen müssen, sondern das Team selbst in der Lage ist, Probleme zu identifizieren und auch selbst zu lösen. Weil so ein Team relativ schnell auf solche Situationen reagieren und Lösungen finden kann.

Anja Kammer: Ja, da fällt mir eine Praxis ein, die das verhindert. Du sagtest ja Entscheidungsspielräume. Ja, Entscheidungsspielräume sind gut, aber kann ich auch auf dem Produktionssystem agieren? Oftmals sind die Berechtigungen auf Produktionssystemen eingeschränkt, selbst für die Entwicklungsteams. Diese können dann bei einem Incident nicht schnell Dinge fixen, und es führt dazu, dass sie erst ihre -Minuten-Pipeline ausführen müssen, die als einzige in der Lage ist, auf das Produktionssystem zuzugreifen. Das wäre dann ärgerlich. Aber wie schaffen es Organisationen, so viele Rechte einzuräumen, dass im Ernstfall auf das Produktivsystem zugegriffen werden darf, aber nur im Ernstfall? Ich weiß nicht, ob das so funktioniert.

Kofi Jedamzik: Das hängt natürlich immer davon ab, welche Ziele ich verfolge oder welche Qualitätsziele ich am Ende des Tages erfüllen muss und wo ich die Balance finde. Es gibt natürlich auch Möglichkeiten, dass ich grundsätzlich Teams nur eingeschränkten Zugriff auf bestimmte Systeme gebe. Wenn ich aus Business-Sicht aber der Meinung bin, im Zweifelsfall ist es wichtig, dass dieser Prozess, warum auch immer, nicht verfügbar sein darf und ich dafür sorgen muss, dass das System innerhalb von Minuten wieder anlaufen kann, kann ich mir natürlich Strukturen und Prozesse überlegen, wo ich Teams die Möglichkeit gebe, so einen – mir fällt jetzt gerade der konkrete Begriff nicht ein, aber im Prinzip so einen – Notfallschalter umlegen kann, dass das Team dann mehr Rechte bekommt, dass das vielleicht irgendwo aufpoppt, was das Team gerade macht, weil ich ja trotzdem vielleicht noch diesen Sicherheitsgedanken dahinter habe. Dass das eigentlich eher der Ausnahmefall sein soll und nicht die Regel ist. Das heißt, in der Regel arbeiten die Teams nur mit beschränkten Rechten. In solchen Ausnahmesituationen, was dann ja in dem Fall der Fall ist, bekommen sie mehr Rechte, um diesen Incident zu lösen. Das wäre eine Möglichkeit, so etwas umzusetzen.

Anja Kammer: Sehr gut.

Kofi Jedamzik: Und die vierte Eigenschaft, die David Woods bei resilienten Systemen gefunden hat, ist die Eigenschaft, wie ich nachhaltig mit dem Thema umgehe. Es geht mehr oder weniger um die Lernfähigkeit von resilienten Systemen, dass ich mich kontinuierlich an sich immer verändernde Umgebungsparameter anpasse. Wie kann ich regelmäßig schauen, dass mein System noch resilient ist? Es geht um den Lernprozess, der dahinter steckt. Als konkretes Beispiel kann ich dort Chaos Engineering Tests durchführen, um mein System regelmäßig auf Resilienz zu testen. Das ist eine Möglichkeit.

Anja Kammer: Aber Chaos Engineering, wird das wirklich in der Praxis gemacht? Ich kenne es nur von Netflix, weil Netflix Chaos Engineering im Grunde erfunden und auch Tooling dafür geschrieben hat. Aber wird das auch in der Praxis gemacht?

Kofi Jedamzik: Ich würde das, also genau, ich kenne viele, vor allem aus Blogartikeln, die das machen. Wenn man den Begriff aber vielleicht ein bisschen abstrakter fasst, am Ende des Tages geht es darum, mein System regelmäßig auf Resilienz zu testen. Was ich in der Vergangenheit bei Unternehmen regelmäßig gesehen habe, ist, dass sie im Prinzip schon diese Szenarien testen: Wenn sie vor allem eigene Rechenzentren betreiben, prüfen sie, ob, wenn ein Rechenzentrum ausfällt, weil der Strom gekappt wird, dann entsprechend alles auf das andere umgeschifft wird, dass die Backup-Mechanismen vorher funktioniert haben, das Einspielen dann wieder funktioniert und dass auch, wenn das Rechenzentrum, was abgeschaltet wurde, wieder verfügbar ist, dann entsprechend auch wieder diese beiden Rechenzentren zusammen existieren können. Das ist etwas, was ich eigentlich in jedem oder in größeren Unternehmen gesehen habe, was natürlich auch wichtig ist. Und das ist etwas, was jedes Unternehmen macht. Dieses kontinuierliche Testen machen schon viele Unternehmen, die das zum Teil relativ weit oben auf der Ebene machen und nicht so sehr auf Anwendungsebene, also, dass man es sich wirklich in der Anwendung selbst ansieht.

Anja Kammer: Ja, ich kenne es auch nur so, dass Unternehmen solche Art von Resilienztests eher in Staging-Umgebungen machen und weniger in der Produktionsumgebung, so wie Netflix propagiert, dass Chaos Engineering während der Produktion gemacht wird, damit Teams auch wirklich Druck dahinter haben, ihre Systeme resilienter zu machen, weil es eben in Produktion passiert. Aber ich kann mir vorstellen, dass es auch ähnlich effektiv ist, wenn man das in Staging-Umgebungen macht und dementsprechend Incentives dahinter stellt.

Kofi Jedamzik: Ja, wobei, wie gesagt, ich kenne das zumindest von bestimmten Kunden aus der Vergangenheit, dass die wirklich auch physikalisch den Strom von Rechenzentren kappen.

Anja Kammer: Auch in Produktion?

Kofi Jedamzik: Dann sind auch Produktionssysteme indirekt betroffen.

Anja Kammer: Ja, ja. Wahnsinn. Ja, das ist spannend. Das Thema Resilienz kam auch irgendwie eher mit dieser Microservices-Welle, habe ich das Gefühl. Es kam zuerst das Thema Microservices, dann kam Site Reliability Engineering, Chaos Engineering, und man hat immer mehr über Resilienz gesprochen. Jetzt ist es langsam wieder ein bisschen abgeflacht, aber dennoch kam Resilienz so wirklich wellenartig hoch. Kommt die Problematik, dass wir mehr über Resilienz reden müssen, von Microservices, oder ist das einfach nur ein Hype-Thema, was zufällig mit den Microservices hochkam?

Anja Kammer: Also brauchten wir schon vor Microservices Resilienz?

Kofi Jedamzik: Das Thema an sich würde ich so definieren, dass es schon vorher wichtige Relevanz hatte. Ich glaube, was durch den Microservice- und Cloud-Hype mitkam, ob das jetzt konkret daran lag, das hat sicherlich damit zu tun, aber es ist sicherlich so, dass unsere Systeme, die wir bauen, in viel mehr vernetzten Umgebungen arbeiten müssen. Das heißt, ich habe viel mehr Interaktion mit anderen Systemen. Ich habe deutlich komplexere Systeme. Da kommen natürlich auch die Microservices ins Spiel, dass ich meine Systeme dann auch physikalisch voneinander ein bisschen mehr trenne, wo ich dann einfach mehr Fehlerquellen im Zweifelsfall habe. Dadurch wurde das Thema zumindest schwieriger zu behandeln oder zu adressieren. Während ich vielleicht, sehr vereinfacht gesagt, vorher nur einen Rechner hatte, wo meine Anwendung als Monolith lief, wo ich im Prinzip viel mehr diesen Aspekt von Null und Eins habe, wo entweder läuft, jetzt mal sehr einfach gesagt, mein Java-Prozess oder läuft nicht. Habe ich jetzt die Problematik, dass meine Anwendung sich über mehrere einzelne Prozesse verteilt, wo jeder einzelne Prozess im Zweifelsfall nicht läuft, wo ein Netzwerk zwischen den Prozessen nicht funktioniert, oder wo das Netzwerk zwischen den Prozessen nur zum Teil funktioniert. Die Fehlerquellen sind aus meiner Sicht einfach mehr geworden und die Fehler sind komplexer an sich geworden, und dadurch wird das Thema auch relevanter, weil ich dann auch komplexere Lösungen im Zweifelsfall brauche. Vielleicht nicht komplexere Lösungen, aber ich muss vielleicht vielschichtiger denken.

Anja Kammer: Vielschichtiger, welche Schichten gibt es denn? Ich habe jetzt schon gehört, vielschichtiger, wir haben erstmal die Hardware, wir müssen uns darum kümmern, dass die Hardware resilient ist oder dass Systeme gegenüber Hardware-Abschaltung resilient sind, gegenüber Netzwerk-Abschaltung. Welche Ebenen gibt es noch?

Kofi Jedamzik: Ich würde mal von unten anfangen. Unten ist bei mir im Prinzip die Code-Ebene der Anwendung. Das ist aus meiner Sicht die erste Schicht, wo ich bestimmte Maßnahmen treffen kann. Dann habe ich die Architektur- oder Infrastruktursicht, so würde ich sie nennen, wo ich mir Gedanken mache, wie ich grundsätzlich dort systematisch gegen Ausfälle und Ähnliches vorgehen kann. Ich gucke mal kurz in meinen Notizen nach, bevor ich was vergesse. Ich habe die Architektur und die Infrastruktur, ich habe die prozessuale Sicht, über die wir vorhin gesprochen haben. Wie kann ich…

[unbekannt]: Beispielsweise bei irgendwelchen Rollouts oder Ähnlichem, wie kann ich in meiner CI/CD Pipeline dafür sorgen, dass bestimmte Sachen funktionieren, so etwas wie Rollback-Mechanismen oder Ähnliches. Und organisatorische Sachen, über die wir auch schon gesprochen haben, was kann ich dort machen? Und ich habe auch die kulturelle Sicht: Was kann ich grundsätzlich in meinem Unternehmen für eine Kultur schaffen, um resilienter zu werden, um Teams resilienter aufstellen zu können und dementsprechend besser mit den Situationen umgehen zu können?

Anja Kammer: Also Teams resilienter aufstellen in Form von: Jeder hat irgendwie Ahnung davon, was bei einem Incident zu tun ist. Das meinst du mit Team-Resilienz. Interessant, ja.

Kofi Jedamzik: Ich kann vielleicht ein Beispiel nennen, was das ganze Thema so ein bisschen motiviert, ist der CrowdStrike-Ausfall vor ungefähr einem Jahr, , wo man im Prinzip bestimmte Sachen sehen kann. Ich finde, im Nachhinein ist man immer schlauer, aber ich glaube, da kann man auch die verschiedenen Maßnahmen auf den verschiedenen Ebenen sehen, was man dort hätte tun können. Vielleicht noch mal zum Hintergrund: Es gab vor einem Jahr einen Ausfall, weil ein Sicherheitsupdate der Sicherheitssoftware nicht funktioniert hatte. Da waren weltweit mehrere Systeme betroffen, ich glaube, in Summe waren das über Millionen Windows-Systeme, die davon betroffen waren. Und das, was es einmal zeigt, ist, dass ein Stück Software, was auf den Windows-Rechnern durch einen Bug oder wie man es auch immer nennen mag, dafür gesorgt hat, dass das komplette Betriebssystem nicht mehr lief oder hochkam und dass dadurch natürlich kaskadierende Fehler entstanden sind. Dann konnten andere Systeme diese Funktionalität nicht nutzen, wenn diese zumindest noch liefen. Einmal habe ich diesen kaskadierenden Effekt, dass Systeme nicht in der Lage waren, diesen Ausfall irgendwie zu isolieren. Angefangen bei dem eigentlichen Sicherheitstool, wo man diese Isolierung hätte umsetzen können, bis hin dazu, dass im Zweifelsfall auch andere Systeme davon betroffen waren, die das eigentliche System hätten nutzen wollen. Man sieht, dass durch die Menge dieser Rechner, die betroffen waren, man hätte sich überlegen können, solche Updates rollierend auszurollen, dass man nicht direkt alle Rechner bespielt, alle Millionen, sondern mit einem gewissen Set an Nutzern oder jetzt in dem Fall an konkreten Rechnern anfängt. Man kann sich da ja steigern mit %, % und %. Das hängt natürlich immer von der Software ab und den Nutzern, die man hat. Das hätte man rollierend machen können, um so zumindest dafür zu sorgen, dass dann nur ein Teil betroffen ist. Und es hat auch gezeigt, dass die Wiederherstellung deutlich – das ist natürlich am Ende des Tages leichter gesagt als getan – aber ich glaube, es hat auch ein bisschen gezeigt, dass man unvorbereitet war und dass dadurch die Wiederherstellung der Systeme im Zweifelsfall länger gebraucht hat, als es hätte sein müssen. Meines Wissens nach war es notwendig, manuell in den Reboot-Prozess einzugreifen. Ich habe jetzt ehrlich gesagt die konkreten Schritte nicht mehr im Kopf, aber es brauchte irgendeine Fachkraft im Zweifelsfall, die sich mit dem Windows-System zumindest einigermaßen auskennt, die dann händisch oder manuell etwas dort anpasst oder bereinigt, um dann den Windows-Rechner neu zu starten.

Anja Kammer: Jetzt ist die Frage, welche Partei ist denn jetzt für die Resilienz verantwortlich? Ist es CrowdStrike, ist es der Serviceanbieter, der hier für mehr Resilienz hätte sorgen sollen? Du hast ja gesagt, den Update in Wellen machen. Das wäre ja dann eine Maßnahme vom Anbieter. Und was ist mit den Nutzenden?

Kofi Jedamzik: Sie hätten sich besser darauf vorbereiten können.

Anja Kammer: Wer hätte sich besser darauf vorbereiten können? Auch die Nutzenden der Software hätten sich besser darauf vorbereiten können, dass, wenn etwas schief läuft, sie schnell wieder das System zum Laufen bringen können.

Kofi Jedamzik: Inwieweit man sich darauf hätte vorbereiten können, darüber kann man natürlich streiten, aber grundsätzlich muss ich natürlich, wenn ich ein System bereitstelle und für mein System andere Systemkomponenten im Zweifelsfall notwendig sind, die ich nicht selbst in der Hand habe, aus meiner Sicht immer das im Hinterkopf behalten, dass dort auch Fehler passieren können. Dass Systeme fehlerhaft agieren können, dass Systeme nicht verfügbar sind. Darauf muss ich auch vorbereitet sein. Das kann ich natürlich auch einmal programmatisch lösen, indem ich das abfange, aber natürlich auch die Situation, das hatte ich ja anfangs beschrieben, wie gehe ich mit Situationen um, die mir komplett unbekannt sind, wo ich im Zweifelsfall genau diese Kreativitätsansätze brauche. Da hätte man, wenn man gewollt hätte – das hängt natürlich auch immer davon ab, wie viel man in dieses Themengebiet investiert – aber da hätte man auch die Möglichkeit gehabt, so vorbereitet zu sein, um im Zweifelsfall auch schneller agieren zu können.

Anja Kammer: Okay, das bedeutet, ich muss mich darauf vorbereiten, dass diese Defekte nicht zu Ausfällen führen. Da fällt mir auch etwas ein: Es war ein Bug in dieser Software. Man hätte das vielleicht auch anders lösen können, indem man auf Seiten des Herstellers, des Softwareherstellers, besser testet, mehr testet, mehr Review-Prozesse einführt und dann dafür sorgt, dass die Resilienz steigt, indem man grundsätzlich darauf achtet, dass besser getestet wird. Dass Reviews in mehreren Schritten passieren, dass es mehr Approvals gibt, vor allem für sicherheitsrelevante Software.

Kofi Jedamzik: Ja, hätte man machen können. Worauf viele Quellen, die sich mit diesem Thema befassen, oder Leute und Bücher, die sich mit dem Thema befassen, regelmäßig hinweisen, ist: Ich habe natürlich einmal diese Phase, wo ich mich auf so einen Incident vorbereiten kann. Ich habe bestimmte Szenarien, die mir im Kopf herumschwirren, wo ich entsprechende Maßnahmen treffen kann. Aber wir haben ja aus dem Beispiel vielleicht auch gelernt, es gibt Situationen oder es treten Fehler auf, auf die ich mich nicht vorbereiten kann, oder es gibt Fehler, die treten vielleicht auch einfach auf. Hardware fällt halt einfach mal aus, da kann ich im Zweifelsfall nichts gegen tun. Das heißt, ich habe nicht nur diese Phase oder die Möglichkeit, mich auf Fehler vorzubereiten, sondern ich sollte mir auch Gedanken machen, wie ich diese Fehler, wenn sie dann doch auftreten, entdecken kann. Die einfachste Lösung ist natürlich durch ein entsprechendes Monitoring, wenn ich sehe, dass bestimmte Dienste, bestimmte Hardwarekomponenten nicht laufen. Und ich muss mir dann natürlich überlegen, wie ich darauf reagiere. Also mir Strategien überlegen, wie ich trotz dieses Fehlers entsprechend meine Funktionalität, die ich dem Nutzer bereitstellen möchte, bereitstellen kann. Dafür habe ich natürlich auch ein Spektrum, wie ich das machen kann. Wir hatten auch schon gesprochen, grundsätzlich den Fehler isolieren. Und was in der Regel häufig daraus folgt, ist, dass ich diese Systeme ja brauche, ansonsten würde ich sie in der Regel auch nicht anbinden, aber sie sind vielleicht nicht so notwendig, um die Grundfunktionalität bereitstellen zu können. Ich kann mir im Prinzip Fallback-Szenarien überlegen. Als Beispiel, wenn ich irgendeinen Service nutze, das ist auch ein Beispiel, das im Netflix-Kontext gerne genannt wird: Wenn ich irgendeinen Service habe, der beispielsweise personalisierte Filmempfehlungen dem Nutzer bereitstellt. Wenn der aus irgendwelchen Gründen nicht verfügbar ist, möchte ich nicht, dass die Netflix-Seite an sich nicht mehr funktioniert, dass ich als Nutzer nicht mehr einen Film aussuchen und mir anschauen kann, sondern was ich mir dort als Fallback überlegen kann, ist, dass ich anstatt so einer personalisierten Empfehlungsliste eine statische irgendwo hinterlegt habe und diese dann immer zurückspielen kann.

Anja Kammer: Jetzt fällt mir auch wieder ein, was ich vorhin sagen wollte, als wir über Microservices gesprochen haben. Du hast ja gesagt, dass die Erhaltung von Resilienz mit Microservices komplexer wird. Aber haben wir nicht eigentlich auch Microservices unter anderem aus dem Grund erschaffen, damit unser System robuster und resilienter wird, dadurch, dass eben, wenn ein System ausfällt, das gesamte andere System immer noch arbeiten kann? Haben wir also weniger Resilienz bekommen, dadurch, dass wir mehr Resilienz schaffen wollten, weil es jetzt komplexer geworden ist? Oder kam diese Robustheit gegenüber einzelnen Modulausfällen einfach nur nebenbei, weil wir Microservices aus anderen Gründen machen wollten, um den Monolithen aufzubrechen, damit mehrere Teams daran arbeiten können, zum Beispiel? Und diese Robustheit gegenüber anderen Ausfällen kam irgendwie so kostenlos dazu.

Kofi Jedamzik: Ich glaube, es gibt eine Vielzahl von Gründen, Microservices zu nutzen. Resilienz kann da auch ein Punkt sein. Wenn das ein Punkt ist, müsste man ihn entsprechend korrekt behandeln. Was mir eine Microservice-Landschaft erstmal bringt, ist in der Regel eine komplexere Systemlandschaft als Monolithen, zum Beispiel. Und wie gesagt, das erhöht natürlich die Wahrscheinlichkeit, dass dort Fehler auftreten, die, wenn ich sie nicht richtig behandle – das ist, glaube ich, wichtig zu sagen – dann zu kaskadierenden Fehlern führen können, wodurch mein System dann auch wieder in Summe nicht richtig funktioniert. Dadurch, dass die Wahrscheinlichkeit einfach höher ist, kann man natürlich erstmal daraus schlussfolgern, dass die Resilienz des gesamten Systems erstmal darunter leidet, dass ich mich für so eine Microservice-Landschaft entschieden habe. Ich kann das aber jetzt in dem konkreten Fall natürlich auch umdrehen, indem ich sage, ich habe nicht mehr diesen großen Monolithen, wo ich im Zweifelsfall diesen binären Zustand von Null und Eins habe, sondern ich habe vielleicht – das kann ich beim Monolithen natürlich zum Teil auch machen – aber ich habe vielleicht mehr die Möglichkeit, bestimmte Fehler an bestimmten Systemen zu isolieren und dafür zu sorgen, dass, wenn ich beispielsweise zehn Services habe und einer funktioniert nicht richtig, die restlichen neun im Zusammenspiel immer noch eine nützliche Funktionalität dem Benutzer bereitstellen können. Wie gesagt, als Beispiel das mit den Filmempfehlungen bei Netflix. Und wie gesagt, das kann ich beim Monolithen natürlich auch so gestalten, aber vielleicht auf der Ebene ist es gegebenenfalls ein bisschen einfacher, weil ich da auf einer anderen Ebene unterwegs bin und einfacher Prozesse isoliert voneinander laufen lassen kann, sodass, wenn die mal, warum auch immer, nicht funktionieren oder ein bisschen salopp gesagt, Amok laufen, die anderen nicht beeinflussen. Beim Monolithen habe ich dann im Zweifelsfall wieder mehr Szenarien, wenn irgendwie, keine Ahnung, ein Threadpool oder Ähnliches voll läuft oder wenn, warum auch immer, ein Prozess für die Filmempfehlungsberechnung – kann man sich jetzt schwer vorstellen – aber wenn dort dann der gesamte Memory, warum auch immer, verwendet wird, habe ich einfach eingeschränktere Möglichkeiten, solche Fehler zu isolieren. Was nicht heißt, dass es nicht geht, das will ich mal dazu sagen.

Anja Kammer: Du hattest ja auch gesagt, es kommt immer darauf an, welches Modul jetzt so kritisch für das System ist, ob es jetzt ein Ausfall ist oder nicht. Wie bewerte ich denn, welches Modul besonders kritisch ist, welches besonders resilienter sein sollte und wo ich mein Geld und meine Zeit investiere? Weil dadurch, dass Resilienz so komplex ist, ist es wahrscheinlich auch sehr teuer. Ich möchte mir vorher überlegen, welche Module ich priorisiere, welche Module besonders resilient sein müssen, weil sie eben dazu beitragen, dass die Nutzererfahrung nicht leidet.

Kofi Jedamzik: Am Ende des Tages ist das etwas, was das Business vorgeben muss, aus meiner Sicht. Unternehmen betreiben ja die Systeme, um in der Regel Umsatz zu machen, Geld zu machen, Umsatz einzufahren. Das heißt, ich kann natürlich anhand dieser Business Capabilities, die ich mir definiere, die besonders wichtig sind, die laufen müssen, dann kann ich natürlich Rückschlüsse ziehen, welche Komponenten damit verbunden sind und dann entsprechend, welche Komponenten vielleicht resilienter sein müssen und welche weniger resilient sein müssen. Damit kann ich im Prinzip anfangen. Wenn es jetzt konkret darum geht, wie ich meine Systemlandschaft, wenn ich darauf gucke, resilienter gestalten kann, würde ich genau im Prinzip damit anfangen, was sind – also erstmal mit der Identifikation – was sind wichtige Komponenten für mein Business?

Anja Kammer: Was ist der kritische Pfad, was ist die Cash Cow?

Kofi Jedamzik: Genau. Und würde dann entsprechend versuchen, eine Bestandsaufnahme, eine Ist-Situation der aktuellen Komponenten vorzunehmen. Also im Prinzip zu bewerten.

Anja Kammer: Wie resilient sind die Komponenten gerade? Okay, da sind wir jetzt wieder bei Observability. Welche Metriken muss ich dann sammeln?

Kofi Jedamzik: Man ist bei Observability, aber nicht nur. Ich kann natürlich aus den vergangenen Observability-Metriken, wenn ich sie schon sammle, sehen, wie mein System in der Vergangenheit resilient war. Im Zweifelsfall sehe ich aber auch nicht – es kann natürlich sein, dass mein System die ganzen Jahre durchgelaufen ist, aber es heißt ja nicht, dass es frei von Resilienz-Lücken ist, dass es bestimmte Schwachstellen hat. Es kann natürlich sein, dass mein System, was zehn Jahre lief, auch immer lief, weil beispielsweise ein gewisser Service immer verfügbar war und geantwortet hat. Jetzt kann es natürlich sein, dass, warum auch immer, dieser Service im kommenden Jahr nicht mehr so responsiv antwortet, nicht mehr so verfügbar ist. Und es kann auch in dem Fall dann sogar sein, dass es vielleicht gar kein wichtiger Service ist, aber dass so ein Ausfall beispielsweise dann doch mein System betreffen würde. Das ist das, was ich mit Lücken in den aktuellen Komponenten, Services, Systemen meine. Und davon würde ich eine Bestandsaufnahme erstmal machen. Also, wo habe ich im Prinzip noch den größten Gap zu dem Stand, den ich bei so einer Komponente erreichen möchte, was Resilienz angeht, und wo wir aktuell stehen.

Anja Kammer: Das klingt nach einer sehr großen Aufgabe. Du sagtest ja, man sammelt ja eh schon Metriken, aber da wäre ich mir gar nicht so sicher, ob wirklich jede Komponente so detailliert vermessen wird, dass ich am Ende eine Aussage darüber treffen kann, wie resilient ein System ist. Du hattest ja auch gesagt, manchmal kann man das auch gar nicht erkennen, weil es in letzter Zeit immer gut lief mit den Abhängigkeiten. Aber wir haben ja schon über Resilienz-Testing gesprochen. Vielleicht ist das dann die Lösung, das Gesamtsystem auf Herz und Nieren zu überprüfen, mal Latenz hinzuzufügen und mal Fehler in das System einzufügen und dann zu gucken, wie das System reagiert. Dann könnte ich das für jede Komponente doch schon erarbeiten. Das ist aber eine Heidenarbeit, so etwas zu machen, oder?

Kofi Jedamzik: Das ist eine Möglichkeit. Vielleicht noch mal kurz auf die Metriken zurückzukommen: Ich kann natürlich Metriken aus der Vergangenheit nutzen, um, wenn sie vor allem negativ sind, diese als Indikatoren zu verwenden. Wenn ich weiß, dass mein System immer pünktlich zum Weihnachts-Sale in die Knie geht, dann weiß ich, dass ich da ein Problem habe. Dafür kann ich das natürlich nutzen. Ich kann das Ganze testen und dann verproben. Ich kann natürlich aber auch mit anderen Möglichkeiten herangehen: Ich kann Reviews durchführen, sowohl Code- als auch Architektur-Reviews, und schauen, welche Maßnahmen ich dort grundsätzlich umgesetzt habe. Ein einfachstes Beispiel wäre, wenn ich ein System habe, das ich nicht redundant laufen lasse. Das ist ein einfaches Finding zu sagen: Wenn diese Hardware-Komponente oder diese Instanz mal ausfallen sollte, habe ich im Zweifelsfall ein Problem. Das ist etwas, was ich vielleicht relativ einfach beheben kann, was aus meiner Sicht jetzt weniger Aufwand bedeutet, als einen Test durchzuführen, weil das eine gewisse Vorbereitung, Durchführung und dann auch Auswertung beinhaltet. Gut, das Review auch, aber ich habe da vielleicht mehr die Möglichkeit, in die Breite zu gehen, als im Zweifelsfall konkrete Szenarien durchspielen zu müssen.

Anja Kammer: Aber wenn du Redundanz sagst, dann höre ich da wieder Hochverfügbarkeit raus, und dann klingt das für mich alles sehr teuer. Möchte ich das einfach als grundlegende Annahme für jede Komponente annehmen, okay, ihr braucht immer Redundanz für jedes Modul, oder kann ich da auch Kompromisse eingehen, weil das mir viel zu teuer wäre, allein der Aufwand und aber vor allem auch die Kosten, die dahinter stecken, also auch die Betriebskosten meine ich damit?

Kofi Jedamzik: Das war jetzt ja nur ein Beispiel. Das heißt, wir sind ja noch bei der Ist-Stand-Analyse. Da kann ich das erstmal feststellen.

Anja Kammer: Ich bin schon bei den Lösungen.

Kofi Jedamzik: Das kann ich erstmal feststellen, wo stehe ich da, wo habe ich einen Gap?

Anja Kammer: Das stimmt.

Kofi Jedamzik: Der nächste Schritt, den man dann durchführen müsste, wäre, sich zu überlegen, wie kann ich diese Gaps mit welchen Maßnahmen auflösen? Und dann kann ich mir entsprechend Gedanken darüber machen, wie groß der Kostennutzenfaktor ist.

Anja Kammer: Okay.

Kofi Jedamzik: Also, sowohl was die eigentliche Lösung dann angeht, in dem Fall Redundanz, also, welche Kosten würde es mit sich bringen, ein System redundant hinzustellen, als auch die Umsetzung. Ich muss bei so einer Redundanz – mag es vielleicht einfach sein, das hängt natürlich auch wieder vom System ab – ich kann nicht jedes System einfach doppeln, das ist das eine. Das heißt, um mal bei dem Beispiel zu bleiben, wenn ich dafür auch im Code etwas ändern muss, habe ich im Zweifelsfall Implementierungsarbeit, die dann einhergeht. Also, die Anforderung erstmal definieren, das Ganze umzusetzen, zu testen, das geht natürlich alles mit in die Kosten ein. Aber sich Gedanken darüber zu machen, wo habe ich aktuell die größten Gaps, auf Basis dessen überlegen, welche Lösungsstrategien ich da fahren kann und dann entsprechend aus diesen beiden Kombinationen eine Kostennutzenanalyse machen und dieses Ergebnis nutzen, um…

Anja Kammer: Ja, eine Priorisierung zu machen, oder?

Kofi Jedamzik: Eine Priorisierung zu machen. Das Ganze dann auf eine Roadmap oder Ähnliches zu legen. Wo habe ich vielleicht Quick Wins, die ich innerhalb von einem Quartal beispielsweise lösen kann, als auch, gerade wenn es dann um strategisch wichtige Komponenten geht, die wir im ersten Schritt in der Business-Analyse identifiziert haben, strategische Lösungen, langfristige Lösungen dann zu implementieren, die dann vielleicht auch nicht schnell umgesetzt sind, die in der Regel dann ja auch auf Code-Ebene stattfinden können, sondern das können ja dann auch wieder Maßnahmen sein, die dann ganze Prozesse oder einen Wandel in der Organisation mit sich führen würden.

Anja Kammer: Wir haben die ganze Zeit über Analyse gesprochen und das alles einzuordnen und weniger über die Maßnahmen, was mich immer wieder gebremst hat. Nein, nein, wir sind noch bei der Analyse und noch weniger bei den Maßnahmen. Wollen wir einmal über die Maßnahmen sprechen? Es gibt so viele Maßnahmen, und was ich oft zu hören bekomme ist: Ja, es gibt so viele Maßnahmen, es reicht doch, wenn ich mir eine auspicke und dann habe ich Resilienz, weil viele Resilienzmaßnahmen zahlen ja auf dasselbe Ziel ein. Also, warum sollte ich mehrere Maßnahmen, beispielsweise, warum sollte ich jetzt den Circuit Breaker nutzen, wenn ich auch gleichzeitig Retries verwende, oder warum sollte ich Bulkheading verwenden, wenn ich beispielsweise einen Circuit Breaker nutze? Diese ganzen Begrifflichkeiten sind im Raum. Kannst du die mal einordnen? Was ist ein Circuit Breaker, was ist Bulkheading, und kann ich die kombinieren, oder ergibt es überhaupt keinen Sinn, diese Maßnahmen zu kombinieren?

Kofi Jedamzik: Ich kann auf ein paar eingehen. Mein Vorschlag wäre, in das Buch 'Release’ beispielsweise zu schauen, das können wir sicherlich auch irgendwo verlinken. Da gibt es eine Reihe von Stability Patterns, die genau auf das Resilienzthema eingehen würden. Um vielleicht auf ein paar einfache Maßnahmen einzugehen: Ein Circuit Breaker ist im Prinzip wie ein Sicherungsschalter, der dafür sorgt, dass wenn ich als Client-Service oder als Client feststelle, dass ein anderer Service aus welchem Grund auch immer Fehler reagiert, dass ich dann erstmal versuche, meine Requests bei mir zu behalten. Im Prinzip habe ich dann einen offenen Status bei mir vom Sicherungsschalter.

Anja Kammer: Also, wenn es zu einem Fehler kommt für einen Request, wenn der nicht zurückkommt, ein Timeout passiert oder ein er, dann sage ich, okay, ich schicke dieser Komponente jetzt keine Requests mehr.

Kofi Jedamzik: Genau. Es hat im Grunde vor allem zwei Vorteile: Zum einen gebe ich dem anderen Service die Möglichkeit, sich zu erholen, gerade dann, wenn er Schwierigkeiten hat, sich zu erholen, wenn er weiterhin Anfragen bekommt. Das macht vielleicht vor allem auch Sinn, wenn bestimmte Ressourcen oder Ähnliches vollgelaufen sind, die dann erstmal auf der gegenüberliegenden Seite abgearbeitet werden müssen. Zum anderen gibt es mir die Möglichkeit, schneller auf diesen Fehler reagieren zu können. Wenn ich weiß, dass der Service jetzt die nächsten Minuten nicht korrekt antworten wird, dann muss ich ihn nicht fragen und muss nicht auf eine fehlerhafte Antwort warten, sondern kann dann direkt entsprechend auf diesen Fehlerzustand reagieren, sei es durch den Fallback, den wir vorhin besprochen haben, oder durch eine Fehlermeldung an den Nutzer: 'Ich kann diese Funktion gerade nicht ausführen’, weil sie Fehler verursacht.

Anja Kammer: Versuchen Sie später noch mal sozusagen. Oder auch, dass diese Aufgabe erstmal in eine Queue gespeichert und dann später noch mal verschickt wird, oder?

Kofi Jedamzik: Genau, das wäre auch eine Möglichkeit. Eine andere einfache Möglichkeit ist, eine Strategie zu fahren, dass ich Retries oder Ähnliches einbaue. Das heißt, wenn ich ein System aufrufe und ich bekomme keine Antwort oder vielleicht auch eine Fehlerantwort, dass ich das dann einfach noch mal versuche. Es können beispielsweise Probleme auf Netzwerkebene passieren, dass ein Service nicht antwortet. Es können natürlich auch temporäre Fehler im Service sein, weil er vielleicht gerade neu deployed wird und deswegen nicht erreichbar ist und das ganze Handling da nicht sauber gemacht worden ist. Das heißt, eine einfache Möglichkeit, so etwas erstmal abzudecken, ist, selbst so einen Retry-Mechanismus einzubauen, der zeitversetzt die Anfrage dann noch mal rausschickt, die er eigentlich rausschicken wollte.

Anja Kammer: Das heißt, ich mache dreimal ein Retry, und wenn es dann immer noch nicht geklappt hat, dann nutze ich den Circuit Breaker und warte noch mal weitere Minuten und versuche es dann noch mal zu schicken, oder?

Kofi Jedamzik: Die Kombination, das ist vielleicht ein Punkt, den man grundsätzlich beachten muss, und ich glaube, das ist auch die Frage, die du meintest. Zum einen habe ich unterschiedliche Lösungsstrategien, um bestimmte Problemszenarien zu adressieren, und deshalb macht es gegebenenfalls auch Sinn, natürlich mehrere Lösungsstrategien in meinem Service umzusetzen oder vorzusehen.

Anja Kammer: Also, ich kann das schon miteinander kombinieren.

Kofi Jedamzik: Ich kann das schon kombinieren. Genau, ich muss aber natürlich aufpassen, dass bestimmte Lösungsstrategien nicht in Konflikt kommen. Das, was wir jetzt gerade besprochen hatten: Ich habe einen Circuit Breaker, um dem anderen Service die Möglichkeit zu geben, sich zu erholen, und ich schicke keine Requests raus. Und wir haben gerade die Lösungsstrategie beschrieben, dass ich eigentlich Retries machen möchte und im Zweifelsfall dann wieder doch mehr Requests an den Service schicke, obwohl er gerade fehlerhaft geantwortet hat. Das heißt, ich muss mir bei solchen Sachen immer überlegen, ob ich konfliktäre Lösungsstrategien nutze, und wenn ich das nutze, muss ich mir überlegen, wie diese miteinander koexistieren können. In dem Fall ist es genau so: Ich nutze grundsätzlich Retries, weil ich weiß, dass aus welchem Grund auch immer bei jedem zehnten Request mal der andere Service einen Schluckauf hat und nicht antwortet. Wenn ich aber sehe, dass er fünfmal oder zehnmal hintereinander fehlerhaft geantwortet hat, weiß ich als Service, dass da grundsätzlich etwas nicht funktioniert, und dann würde ich entsprechend diesen Circuit Breaker-Mechanismus nutzen.

Anja Kammer: Ja, genau. Man versucht es nicht unendlich weiter, sondern man bricht irgendwann den Versuch ab und macht ein anderes Handling.

Kofi Jedamzik: Genau. Worauf ich auch aufpassen muss, ist, dass ich Lösungsstrategien habe, die ich auf verschiedenen Ebenen oder Stellen einarbeiten kann. Um bei den Retries zu bleiben: Ich kann das programmatisch direkt im Code lösen. Die einfachste Möglichkeit wäre im Prinzip eine Vorschleife, die es dreimal versuchen würde mit einer Abbruchbedingung. Ich habe aber auch im Zweifelsfall bestimmte Komponenten oder Services in meiner Infrastruktur, zum Beispiel. Ein konkretes Beispiel wäre, wenn ich Service Mesh oder Ähnliches nutze und das durch mein Kubernetes Cluster bereitgestellt wird. Da habe ich auch die Möglichkeit, auf Netzwerkebene Retries durchzuführen. Ich muss darauf achten, dass sich das nicht in die Quere kommt, beziehungsweise ich sollte hier einfach klare Regeln festlegen, welche Lösungsstrategien wo implementiert werden müssen. Weil ansonsten habe ich im Zweifelsfall das Problem, dass ich aus meinem Java Code dreimal versuchen würde, den anderen Service aufzurufen. Das wird nicht funktionieren – wir gehen jetzt immer davon aus, dass der andere Service nicht erreichbar ist – und dann habe ich noch mal auf Netzwerkebene, wo der Service Mesh eingreift, der hätte eine ähnliche Regel und würde es auch noch mal dreimal versuchen. Das heißt, aus meinem Java-Prozess würde ich drei Requests rausschicken, und für jeden Request, der diese Netzwerkebene erreicht, würde mein Service Mesh auch noch mal drei Requests machen, weshalb ich dann bei neun lande. Und das ist, glaube ich, in der Regel nicht das Verhalten, was ich haben möchte. Das heißt, was hier hilft, sind einfach klare Verantwortlichkeiten zu trennen. Also, ich sollte mir darüber Gedanken machen, das entsprechend definieren und dann auch irgendwo dokumentieren und niederschreiben.

Anja Kammer: Das bedeutet, es gibt schon eine Daseinsberechtigung für solche globalen Regeln, wie: In unserem System müssen alle Services den Circuit Breaker beispielsweise mittels Service Mesh implementieren, und wir haben das einfach für alle Services eingeschaltet, weil wir ein Service Mesh gefunden haben und alle sollen das jetzt benutzen. Es gibt schon eine Daseinsberechtigung dafür, oder meinst du, das ist generell Quatsch und jeder Service sollte selbst entscheiden dürfen, ob wir in unserem Service Mesh Proxy einen Circuit Breaker nutzen, ja oder nein?

Kofi Jedamzik: Es gibt eine Daseinsberechtigung, das würde ich aber auch, also, ich würde das nicht mit einer klaren Antwort versehen. Aus meiner Sicht ist beides möglich, und es gibt gute Gründe, weshalb ich das so oder so machen möchte. Das hängt immer stark von den technischen Anforderungen ab, aus meiner Sicht, als auch davon, wie die Teams in einem Unternehmen beispielsweise agieren. Also, wie viel Verantwortung sind die Teams gewohnt, selbst zu übernehmen? Das kann ja auch ein Prozess sein, der sich dann entwickelt. Vielleicht möchte ich am Anfang erstmal vieles global eingestellt haben, damit es erstmal drin ist, und sukzessiv kann ich dann auch mehr solche Thematiken in die Teams verlagern. Von daher ist aus meiner Sicht beides möglich. Ich kann aber auch mit einer Landschaft leben, in der es grundsätzlich viele globale Regeln gibt. Das hat halt alles Vor- und Nachteile, die ich dann einfach im Zweifelsfall abwägen muss.

Anja Kammer: Ich glaube, das Spannendste wird dabei sein zu argumentieren, wer denn jetzt nun verantwortlich ist. Ich glaube, das ist eher das Spannende, also die organisatorische Kommunikation.

Kofi Jedamzik: Das ist es, genau. Also einmal das auszumachen, und ansonsten, was aus meiner Sicht gut funktioniert, ist, wenn es irgendwo ein Regelset gibt, Richtlinien, Vorgaben oder Ähnliches, die dann genau diese Trennung der Verantwortlichkeiten definieren. Es kann beispielsweise eine Makroarchitektur sein, die solche Regeln vorgibt, die auch grundsätzlich andere Regeln vorgibt, woran sich jede Komponente im System halten muss. Und da kann ich natürlich genau diese Verantwortlichkeiten dann auch verankern, die definieren, wofür ein Modul oder ein System selbst verantwortlich ist und was gegebenenfalls auch global geregelt wird und wo ein System dann im Prinzip kein Mitspracherecht hat, jetzt mal ganz hart gesagt.

Anja Kammer: Eine Maßnahme, über die wir noch nicht gesprochen haben, ich aber angekündigt habe, war Bulkheading. Was ist mit Bulkheading? Wo implementiere ich das und kann ich das mit anderen Maßnahmen kombinieren?

Kofi Jedamzik: Bulkheads kommt sinngemäß daher, dass ich versuche, gewisse Fehlerressourcen oder Fehler zu isolieren. Eine Möglichkeit ist grundsätzlich, Ressourcen in gewisse Gruppen zu gruppieren, sodass ich dort gewisse Pools habe. Das Einfachste wäre auf Anwendungsebene beispielsweise, wenn ich für bestimmte Aufgaben nicht meine gesamten Threads zur Verfügung stellen würde, sondern dass ich dort nur einen Pool von Threads bereitstelle. Das sorgt dafür, dass, wenn ich diesen Prozess berechnen möchte, er maximal zum Beispiel nur sich von fünf laufenden Threads bedienen kann, nutzen kann, um diese Berechnung zu tun. Und das hat den Vorteil, dass, wenn meine Anwendung grundsätzlich mit mehr Threads arbeiten könnte, andere Prozesse in meiner Anwendung weiterhin funktionieren könnten, selbst wenn diese Berechnung gerade unter Last steht. Im schlimmsten Fall, wenn ich das nicht hätte, würden all meine Threads blockieren und dann könnte andere Funktionalität nicht mehr bereitgestellt werden.

Anja Kammer: Das bedeutet, für meine Cash Cow oder für mein wichtiges User-Szenario habe ich mehr Threads zur Verfügung als für nebenläufige Aktivitäten, die nicht so wichtig oder kritisch für das System sind.

Kofi Jedamzik: Genau. Ich kann das natürlich einmal über die Anzahl steuern, oder ich kann das grundsätzlich darüber steuern, wie viele Ressourcen ich solchen Pools in dem konkreten Fall gebe. Es geht aber vor allem auch um die Idee, dass ich diesen Ressourcenpool beschränke, damit ich nicht Gefahr laufe, dass durch einen Fehler oder Ähnliches, oder durch Einwirkung von außen, gerne auch durch einen böswilligen Angriff beispielsweise, der dann bestimmte Berechnungen mehrmals triggert, meine gesamte Anwendung außer Kraft gesetzt wird, weil dann gewisse Ressourcen komplett für diesen Prozessschritt blockiert werden würden.

Ich kann das natürlich, genau. Ich kann das, also, der eine Schritt ist, ich überlege mir gewisse Ressourcenpools, um bestimmte Fehlerquellen zu isolieren, wenn diese auftreten. Ich kann diese Ressourcenpools aber auch dazu nutzen, um eine Priorisierung damit indirekt festzulegen, indem ich gewissen Ressourcenpools mehr oder weniger gebe.

Sollte ich in der Regel auch tun. Genau, das ist das eine. Ich kann dieses, ich glaube, das kennen wir ja, also, ich kann das natürlich auch auf Infrastrukturebene umsetzen.

Anja Kammer: Bulkheading.

Kofi Jedamzik: Genau. Und das machen wir ja in der Regel auch. Das Einfachste ist natürlich, dass ich auf Infrastrukturebene bestimmten Prozessen gewisse Ressourcen bereitstellen kann. Das wird vor allem dann interessant, wenn ich mich in einem Cluster befinde und irgendwelche Container oder Ähnliches starte. Ich will im Zweifelsfall ja auch nicht, dass ein Container plötzlich Amok läuft und die ganzen Ressourcen von dieser Instanz, wo er gerade läuft, sich nimmt und andere Container da nicht mehr laufen können.

Anja Kammer: Also du meinst wirklich Ressourcenlimitierung für den Container, Resource Limits und Requests, darüber reden wir. Okay. Wenn wir über Kubernetes reden würden, muss ich dazu sagen.

Kofi Jedamzik: Genau. Ich kann natürlich auch – das ist auch eine Möglichkeit, da wird es natürlich auch wieder ein bisschen komplizierter, je nachdem, was ich damit erreichen will – aber es kann Sinn machen, dass ich versuche, bestimmte Nutzergruppen zu gruppieren. Also, ich habe eine Menge an Nutzern, die kann ich unterteilen. Wir können jetzt mal von dem einfachen Beispiel ausgehen, ich unterteile die einfach nach dem Anfangsbuchstaben des Vornamens.

Das heißt, ich habe beispielsweise dann auch, nehmen wir an, wir haben Instanzen, wo meine Anwendung drauf läuft, und ich sorge immer dafür, dass Personen mit dem Anfangsbuchstaben A auf Instanz landen, mit dem Anfangsbuchstaben B auf Instanz . Und wenn ein Nutzer genau dieses Fehlerszenario kreiert, wie auch immer, dass er im Prinzip nur dafür sorgt, dass die eine Instanz ausfällt oder nicht mehr funktionsfähig ist, aber alle anderen Instanzen noch funktionieren. Das hat den Vorteil, dass dann eine gewisse Nutzergruppe – das sind dann blöderweise alle Leute mit dem Vornamen Anfangsbuchstaben A – dann nicht mehr das System nutzen können, aber dafür können noch andere Nutzergruppen, also der Großteil meiner Anwender, weiterhin ihr System nutzen.

Anja Kammer: Und was ist, wenn alle diese Instanzen, alle Instanzen dieselbe Datenbank verwenden? Dann würde die Datenbank ja durch A überlastet werden, beispielsweise, und alle anderen Instanzen würden davon auch in Mitleidenschaft gezogen werden. Wie löst man das auf?

Kofi Jedamzik: Das kann ich, also, genau, ich muss natürlich immer darauf achten, wie dann im Zweifelsfall diese einzelnen Instanzen doch noch indirekt zusammenhängen. Das kann durch eine gemeinsame Datenbankverbindung passieren. Ich kann natürlich aber dieselbe Strategie auf mehreren Ebenen fahren. Das heißt, ich habe nicht mehr eine geteilte Datenbank für alle Nutzergruppen, sondern ich habe dann auch in dem Fall, sehr vereinfacht gesagt, Datenbankinstanzen für jede Instanz. Das ist eine Möglichkeit. Ich kann natürlich aber auch versuchen, das Ganze über eine Datenbankinstanz abzudecken und dort versuchen, auf Datenbankebene eine gewisse Ressourcenisolierung umzusetzen. Das geht natürlich auch, das geht ganz gut.

Anja Kammer: Vielleicht durch wieder Connection Pools und.

Kofi Jedamzik: Genau.

Anja Kammer: Ja, okay. Das heißt, es geht schon, also mit Bulkheading kann ich auf jeden Fall auch noch andere sehr codenahe Mechanismen kombinieren, weil das sich sozusagen nicht widerspricht.

Kofi Jedamzik: Genau.

Anja Kammer: Ja. Okay, also gerade Bulkheading ist ja auch schon, wenn man es auf Infrastrukturebene implementiert, ganz schön aufwendig, ganz schön teuer, weil diese ganzen Instanzen kosten ja wieder Rechenkapazität, kosten auch wieder, ja, Rechenkapazität. Dementsprechend ist der Betrieb dann ganz schön teuer. Wie entscheide ich mich jetzt für die einen Maßnahmen und die anderen Maßnahmen? Also, wenn ich Architektur-Entscheidungen treffe, dann nutze ich meistens ein ADR, ein Architecture Decision Record. Das mache ich wahrscheinlich hier auch, oder? Wir haben festgestellt, wir brauchen mehr Resilienz für System XY und wir haben verschiedene Alternativen. Es gibt folgende Maßnahmen, je nachdem, manche Maßnahmen können dann aufgelistet werden, irgendwelche Resilienzmaßnahmen, wie wir gerade besprochen haben, und dann könnte zum Beispiel entschieden werden, okay, welche dieser Maßnahmen bietet das beste Kosten-Nutzen-Verhältnis, oder?

Kofi Jedamzik: Also, wir haben ja schon darüber gesprochen, in der Regel sind die Maßnahmen nicht umsonst oder gratis.

Vielleicht gibt es manchmal wenige, die dann doch gratis kommen, aber die meisten nicht. Und wie das auch bei vielen anderen Sachen ist: Ich habe natürlich die Kostenabwägung auf der einen Seite, aber ich habe natürlich auch, wenn ich das Qualitätsmerkmal Verfügbarkeit oder, nehmen wir es in dem Fall, Resilienz nehme, die Eigenschaft, die ich in meinem System hinzufügen möchte. Ich habe prinzipiell immer potenzielle Eigenschaften, die dagegen sprechen könnten. Das muss man natürlich immer von der konkreten Eigenschaft betrachten, ob das so ist und auch von der konkreten Lösung, die man im Zweifelsfall dort implementiert. Sehr vereinfacht gesagt, wenn wir versuchen, zwischen den einzelnen Komponenten Lösungen zu etablieren, die gewisse Sachen machen, kann das beispielsweise mit einem Performanceverlust einhergehen.

Anja Kammer: Woher kommt der Performanceverlust?

Kofi Jedamzik: Wir sprechen beispielsweise im performanten Sinne für den Endnutzer darüber, dass er im Zweifelsfall länger auf seine Seite warten muss.

Anja Kammer: Wenn ich Retries mache, zum Beispiel, und dem Nutzenden nicht Bescheid gebe: Achtung, das System ist nicht verfügbar, sondern die Retries, das dauert natürlich eine Weile.

Kofi Jedamzik: Oder es kann zu einer größeren Verzögerung führen, als wenn ich immer nur einen Request machen würde.

Anja Kammer: Das stimmt.

Kofi Jedamzik: Das ist ein Punkt. Ich habe natürlich grundsätzlich immer den Punkt, dass jede, oder in der Regel jede, Lösung eine gewisse Komplexität mit sich führt. Ich muss im Zweifelsfall Retry-Mechanismen einbauen, ich muss einen Circuit Breaker Mechanismus einbauen. Vieles gibt es auch heutzutage in Bibliotheken, die ich dann einfach einfügen kann.

Anja Kammer: Aber das Schwierige ist die Einstellung des Circuit Breakers, also wann er wirklich das macht, was er soll und mich nicht behindert.

Kofi Jedamzik: Worauf ich hinaus will, ist: Mit jeder Lösung, die ich neu hinzufüge, wächst die Komplexität meines Gesamtsystems und beeinflusst in der Regel oder häufig auch die Wartbarkeit meines gesamten Systems. Das heißt, ich muss überlegen: Je mehr Lösungsstrategien ich im Zweifelsfall einbaue, desto – das hört sich jetzt extremer an, als es in der Realität ist, aber nichtsdestotrotz ist es nicht zu vernachlässigen – wird die Wartbarkeit in der Regel etwas negativ davon beeinflusst. Sei es auch durch Bibliotheken, die das Ganze für mich abnehmen oder einen Großteil abnehmen, bis auf die Konfiguration – darüber können wir auch noch mal sprechen. Ich habe trotzdem eine neue Abhängigkeit, die ich einmal konfigurieren muss, im Zweifelsfall anpassen muss, ich muss sie auf dem aktuellen Stand halten. Das sind alles Aufwände, die hinzukommen und nicht da wären, wenn ich das nicht tun würde. Eine weitere Trade-off-Entscheidung, die man im Zweifelsfall treffen muss, ist die Abwägung, wie resilient mein System sein möchte und wie viel Innovation ich zulassen möchte. Denn je weniger Innovation, also je weniger Änderungsimpulse ich von außen gebe – und das geht in der Regel häufig mit Innovationen einher – desto weniger Fehlerszenarien können eintreten und desto resilienter wird mein System. Das heißt, ich habe diesen Konflikt zwischen der Innovationsfähigkeit, also beispielsweise wöchentlich neue Features auszuliefern, auch experimentell, versus: Ich möchte ein resilientes System haben. Was dort helfen kann, ist beispielsweise mit Error Budgets zu arbeiten. Dass ich mir ein gewisses Kontingent für Fehler vorsehe, das ich für ein bestimmtes Zeitintervall nutzen kann. Und abhängig davon, wie viel ich von diesem Budget aufgebraucht habe, kann ich weiterhin innovativ Features ausliefern. Oder wenn ich feststelle, dass es einfach unglücklich war, was durch neue Releases oder Ähnliches passiert ist und dadurch meine Verfügbarkeit gelitten hat, entscheide ich mich dazu, diese Innovationsschiene etwas herunterzufahren und mehr auf das Thema Resilienz zu setzen, unter anderem dadurch, dass ich weniger neue Features ausliefere.

Anja Kammer: Diese Error Budgets sind auch sehr gut, um im täglichen Doing zu priorisieren und nicht nur im täglichen, sondern wenn wir mit Sprints arbeiten, beispielsweise in einem Sprint Planning zu sagen: Okay, wir nehmen ein paar Tickets mit rein, die an unserer Resilienz arbeiten, weil wir ja ein Budget haben. Ein Budget ist etwas Positives, das kann ich ausgeben und ich sollte das auch ausgeben. Das hilft sozusagen bei einem Sprint Planning, sich die Freiheit zu nehmen, auch etwas für die Resilienz zu tun und nicht immer nur Features zu klopfen. Finde ich sehr gut, wenn man so etwas einführt.

Kofi Jedamzik: Als Ergänzung: Wir haben gerade über Trade-off-Entscheidungen gesprochen. Das muss ich auch bei anderen Themen machen, und was sich dort in der Regel anbietet, ist, ganz normal mit ADRs, Architecture Decision Records, zu arbeiten. Das heißt, ich habe eine Entscheidung zu treffen und muss in einem konkreten Fall die Überlegung anstellen, welche Auswirkungen das auf bestimmte andere Eigenschaften meines Systems hat. Wenn ich beispielsweise einen Circuit Breaker einbauen möchte, kann ich mir überlegen, ob das einen Einfluss auf meine Performance, auf meine Komplexität und im Zweifelsfall auch auf die Wartbarkeit meines Systems hat, sowie wie viele Kosten dahinterstecken würden. Das kann ich alles in diesen ADRs betrachten, festhalten und habe dann auch die entsprechende Dokumentation darüber, aus welchen Beweggründen diese Entscheidung getroffen wurde.

Anja Kammer: Klar. Auch hier kann die Definition von Qualitätszielen helfen. Man sieht schon, normale Architekturarbeit, die wir tun sollten, hilft auch in diesen Dingen, für Resilienz zu sorgen oder für die richtigen Entscheidungen.

Kofi Jedamzik: Für die richtigen Entscheidungen. Es kann immer abhängig von den Qualitätszielen sein, dass Resilienz gar nicht so hoch priorisiert ist wie andere Ziele.

Anja Kammer: Eher Performance und weniger Resilienz. Dann entscheide ich mich manchmal für manche Maßnahmen eben nicht.

Kofi Jedamzik: Genau.

Anja Kammer: Ich denke, wir können über dieses Thema noch weiter reden, vor allem gibt es nicht nur diese drei Maßnahmen, über die wir gesprochen haben. Es gibt noch viel, viel mehr technische Maßnahmen. Darüber könnte man auf jeden Fall noch sehr lange sprechen, aber ich denke, das passt erstmal so. Vielen Dank, dass ich mit dir sprechen durfte, Kofi.

Kofi Jedamzik: Vielen Dank, dass ich hier sein durfte.

Senior Consultant

Anja Kammer ist Senior Consultant bei INNOQ und begleitet Unternehmen auf ihrem Weg in die Cloud. Neben der Beratung zu Entwicklungsprozessen und -plattformen entwickelt sie Cloud-native Webanwendungen in cross-funktionalen Teams. Zudem ist sie akkreditierte Trainerin und Co-Kuratorin für das iSAQB Advanced-Level-Modul CLOUDINFRA.

Senior Consultant

Kofi arbeitet als Senior Consultant in den Bereichen Software-Architektur und Engineering bei INNOQ.