Zum Inhalt springen

Ein Microfrontend darf ausfallen

Microfrontends führen neue Laufzeitgrenzen ein. Besonders bei dynamischer Integration kann ein Remote unabhängig von der Shell nicht erreichbar sein, nicht aktiviert werden oder während der Nutzung scheitern.

Martin Fowler und James Lewis zählen „Design for failure“ zu den prägenden Eigenschaften von Microservice-Architekturen: Anwendungen müssen den Ausfall einzelner Services einkalkulieren und möglichst kontrolliert darauf reagieren.1 Dieselbe Erwartung lässt sich auf Microfrontends übertragen:

Der Ausfall eines Remotes sollte den zugehörigen Produktbereich betreffen, nicht die gesamte Anwendung.

Das ist kein Argument gegen dynamische Microfrontends, sondern eine Folge verteilter Auslieferung. Zusätzliche Autonomie erzeugt zusätzliche Fehlerzustände. Eine Architektur darf deshalb nicht nur für den erfolgreichen Zustand entworfen werden.

Eine verteilte Architektur, die nur funktioniert, solange alle Teile verfügbar sind, ist lediglich ein verteilter Happy Path.

Entscheidend ist nicht, ob ein Remote ausfallen kann, sondern wie weit sein Ausfall reicht.

Bei dynamischen Microfrontends kann die Shell verfügbar sein, während ein einzelnes Remote-Artefakt nicht geladen wird. Ein Manifest kann fehlen, ein Server nicht antworten oder ein Artefakt unvollständig ausgeliefert worden sein. Hinzu kommen Fehler während der Aktivierung und innerhalb des bereits gestarteten Remotes.

Diese Zustände sind nicht automatisch ein Zeichen schlechter Architektur. Sie entstehen dadurch, dass Teile unabhängig betrieben werden. Diese Unabhängigkeit hat jedoch nur dann praktischen Wert, wenn die Plattform auch mit dem Scheitern eines Teils umgehen kann.

Ein Microfrontend ist erst dann wirklich unabhängig, wenn auch sein Ausfall eine begrenzte Reichweite besitzt.

Der Titel ist bewusst zugespitzt. Er erklärt ein Remote weder für unwichtig noch seinen Ausfall für akzeptabel. Geschäftskritische Fähigkeiten dürfen nicht beliebig unzuverlässig sein, nur weil sie in einem eigenen Remote liegen.

Der betroffene Use Case muss trotzdem nicht vollständig weiterfunktionieren. Fällt das Rechnungs-Remote aus, kann die Rechnungsbearbeitung nicht verfügbar sein. Resilienz verlangt keine Ersatzimplementierung in der Shell.

Der sinnvolle Anspruch ist kleiner – und zugleich architektonisch anspruchsvoller:

Kein sinnvoller Anspruch:
└── Die ausgefallene Fähigkeit funktioniert trotzdem vollständig
Sinnvoller Anspruch:
├── Der Fehler bleibt im betroffenen Bereich
├── Das übrige Produkt bleibt bedienbar
├── Der Zustand wird verständlich dargestellt
└── Wiederholung oder Rückkehr ist möglich

Der Fehler ist einkalkuliert und technisch begrenzt. Navigation und andere Produktbereiche funktionieren weiter. Der betroffene Bereich zeigt einen verständlichen Zustand; Wiederholung, Rückkehr und gezielte Diagnose bleiben möglich.

Resilienz bedeutet nicht, dass der betroffene Use Case trotz Ausfall weiter funktioniert. Sie bedeutet, dass nicht zusätzlich das gesamte Produkt ausfällt.

Nicht jeder Remote-Ausfall entsteht in derselben Phase. Für die Integration ist es hilfreich, mindestens drei Fehlerklassen zu unterscheiden.

Der erste Fehler entsteht vor der Aktivierung. Die Shell versucht, ein Manifest, ein JavaScript-Artefakt oder einen dynamischen Einstiegspunkt zu laden, erhält aber innerhalb eines sinnvollen Zeitraums kein verwendbares Ergebnis.

Mögliche Ursachen sind:

  • ein nicht verfügbares Remote-Manifest,
  • ein nicht erreichbares JavaScript-Artefakt,
  • ein Ausfall von CDN oder Server,
  • ein Netzwerkfehler,
  • ein Timeout,
  • ein unvollständig oder fehlerhaft ausgeliefertes Artefakt.

Die Shell muss diesen Zustand innerhalb eines sinnvollen Zeitraums erkennen. Ein dauerhaft sichtbarer globaler Ladeindikator ist kein Fallback. Der betroffene Bereich benötigt einen definierten Fehlerzustand; die übrige Anwendung darf nicht unbegrenzt warten.

In der zweiten Fehlerklasse wurde das Artefakt geladen, aber Bootstrap, Mounting oder Initialisierung schlagen fehl.

Eine Initialisierung kann eine Exception werfen, ein Plattformadapter fehlen, das Mounting scheitern oder ein Integrationsvertrag nicht erfüllt sein. Auch eine nie erfolgreich endende Initialisierung gehört dazu.

Für die Fehlerreichweite ist entscheidend, dass die Shell die Aktivierung als gescheitert behandelt und den Mounting-Bereich in einen definierten Fehlerzustand überführt. Ein geladener Einstiegspunkt ist noch kein gestartetes Remote.

Die dritte Fehlerklasse tritt nach erfolgreicher Aktivierung auf. Das Remote ist sichtbar und wird verwendet, wirft aber später einen nicht behandelten Fehler.

Das kann durch einen Render- oder Templatefehler geschehen, durch eine ungefangene Exception, durch fehlerhafte asynchrone Verarbeitung, durch einen unerwarteten Zustand oder durch einen nicht behandelten Fehler innerhalb eines Use Cases.

Auch der laufende Produktbereich benötigt eine wirksame Grenze, damit ein später auftretender Fehler nicht den gesamten sichtbaren Anwendungsbaum zerstört.

Ein separates Repository, ein eigenes Build-Artefakt und ein unabhängiges Deployment erzeugen organisatorische und technische Grenzen. Sie erzeugen aber nicht automatisch eine isolierte Laufzeit.

Getrennte Deployments erzeugen noch keine getrennten Fehlerbereiche.

Remotes im selben Browserdokument und JavaScript-Kontext teilen wesentliche Ressourcen: Main Thread, Browserobjekte und den sichtbaren Dokumentbaum.

Ein Remote kann das übrige Produkt beispielsweise beeinträchtigen durch:

  • ungefangene Fehler außerhalb einer wirksamen Integrationsgrenze,
  • globale Event-Handler,
  • globale CSS-Regeln,
  • Veränderungen gemeinsam genutzter Browserobjekte,
  • blockierenden synchronen Code,
  • unkontrollierte globale Seiteneffekte.

Diese Wirkungen benötigen unterschiedliche Gegenmaßnahmen. Ein Renderfehler ist etwas anderes als blockierender Code; globale CSS-Regeln werden nicht durch einen Error Handler begrenzt.

Das Wort Microfrontend erzeugt keine Fehlergrenze.

Ein globaler Error Handler kann Fehler protokollieren und damit betrieblich wertvoll sein. Er isoliert jedoch nicht automatisch den betroffenen Bereich. Ein frameworkeigener Error Boundary kann bestimmte Fehler innerhalb eines Komponentenbaums abfangen, deckt aber nicht zwangsläufig asynchrone Fehler, globale Seiteneffekte oder Fehler außerhalb seines Zuständigkeitsbereichs ab.

Die wirksame Fehlergrenze muss zum konkreten Integrationsmodell passen.

Der natürliche Ort für eine bewusste Fehlergrenze ist der Integrationspunkt zwischen Plattform und Remote. Dort kennt die Shell den technischen Lebenszyklus des eingebundenen Teils, ohne dessen Fachlogik übernehmen zu müssen.

Ein mögliches Modell sieht so aus:

Shell
└── Remote Boundary
├── Loading
├── Mounted Remote
├── Activation Error
└── Runtime Fallback

Die Shell oder ein Integrationsadapter kontrolliert dabei die technischen Übergänge:

  1. Das Laden beginnt.
  2. Ein Timeout oder Ladefehler wird erkannt.
  3. Das Mounting wird versucht.
  4. Fehler während der Aktivierung werden abgefangen.
  5. Bei einem Fehler wird ein definierter Fallback dargestellt.
  6. Ein erneuter Versuch kann angeboten werden.
  7. Bei einem Wechsel oder Retry wird eine notwendige Bereinigung ausgeführt.

Diese Verantwortung ist Plattformlogik. Sie erfordert kein fachliches Wissen über Rechnungen, Aufgaben, Bestellungen oder Planungen.

Die Plattform muss wissen, dass ein Remote nicht verfügbar ist. Sie muss nicht wissen, welche fachliche Operation darin gescheitert ist.

Genau darin liegt die wichtige Trennung: Die Shell kontrolliert den technischen Lebenszyklus. Das Remote bleibt für seine fachlichen Zustände und Fehler verantwortlich, solange es selbst noch handlungsfähig ist.

Der Mounting-Punkt ist dabei die äußere Fehlergrenze der Plattform, nicht die einzige Fehlerbehandlung des Remotes. Das Remote bleibt für erwartbare fachliche Fehler und seine internen Zustände verantwortlich. Die Integrationsgrenze schafft jedoch einen Ort, an dem Laden, Aktivierung, äußerer Laufzeitfehler, Fallback und Wiederherstellung bewusst koordiniert werden.

Eine Gegenüberstellung zeigt ein separat ausgeliefertes Remote ohne kontrollierte Fehlergrenze und eine bewusste Integrationsgrenze mit Fehlererkennung, lokalem Fallback und weiterhin nutzbarer Anwendung.

Die Shell kann den Ausfall eines Remotes begrenzen. Sie ist jedoch selbst Teil der Fehlerarchitektur.

Remote fällt aus
└── ein Produktbereich ist nicht verfügbar
Host fällt aus
└── die zusammengesetzte Anwendung ist nicht verfügbar

Der Host ist der gemeinsame Einstiegspunkt der zusammengesetzten Anwendung. Er stellt die Navigation bereit, aktiviert Remotes, vermittelt Plattformverträge und zeigt Fallbacks. Fällt er vollständig aus, kann er keine dieser Aufgaben mehr erfüllen.

Die Shell kann den Ausfall eines Remotes begrenzen. Ihren eigenen vollständigen Ausfall kann sie nicht innerhalb derselben Anwendung auffangen.

Das ist eine reale Grenze des Modells: Die Instanz, die Fehler anderer Teile begrenzt, muss selbst verfügbar sein.

Damit gewinnt die Forderung nach einer fachlich dünnen Shell eine weitere Bedeutung: Mehr volatile Fachlogik vergrößert auch ihre Ausfallwirkung.

Für die Shell folgen daraus klare Anforderungen:

  • geringe fachliche Volatilität,
  • stabile Plattformverträge,
  • robuste Auslieferung,
  • wenige unnötige Laufzeitabhängigkeiten,
  • gute Beobachtbarkeit,
  • kontrollierte Änderungen,
  • klarer technischer Besitz.

Die Shell muss nicht um jeden Preis klein, aber als gemeinsamer technischer Rahmen verlässlich sein.

Die Grafik vergleicht einen lokal begrenzten Remote-Ausfall mit einem vollständigen Host-Ausfall. Beim Remote bleiben Navigation, andere Remotes und ein lokaler Fallback verfügbar; beim Host ist die gesamte zusammengesetzte Anwendung betroffen.

Ein Remote-Artefakt ist noch keine eigenständige Anwendung

Abschnitt betitelt „Ein Remote-Artefakt ist noch keine eigenständige Anwendung“

Bei dynamischen Microfrontends kann ein Remote theoretisch weiterhin erreichbar sein, obwohl der eigentliche Host nicht verfügbar ist. Diese Aussage ist jedoch nur unter zusätzlichen Voraussetzungen richtig.

remoteEntry.js
eigenständig navigierbares Produkt

Ein Remote-Artefakt ist ein technischer Einstiegspunkt. Es besitzt nicht automatisch Navigation, Authentifizierungskontext oder alle notwendigen Plattformadapter.

Für einen direkten Aufruf benötigt das Remote einen eigenständigen Einstiegspunkt oder einen Mini-Host:

Remote
├── Integration im eigentlichen Host
└── eigenständiger Einstiegspunkt oder Mini-Host

Ein Mini-Host kann Routing, Theme, Locale, Authentifizierungskontext, Plattformadapter und API-Anbindung bereitstellen.

Ein dynamisches Remote kann unabhängig vom eigentlichen Host erreichbar bleiben, wenn es zusätzlich über einen eigenständigen Einstiegspunkt betrieben wird. Die bloße Erreichbarkeit seines Remote-Artefakts genügt nicht.

Daraus folgt keine allgemeine Pflicht. Ein Mini-Host kann auch ausschließlich für Entwicklung und Tests existieren und muss nicht Teil der produktiven Ausfallstrategie sein.

Ob ein Remote auch ohne den eigentlichen Host als Produktzugang betrieben wird, ist eine bewusste Produkt- und Betriebsentscheidung – keine automatische Eigenschaft dynamischer Integration.

Statische und dynamische Integration scheitern unterschiedlich

Abschnitt betitelt „Statische und dynamische Integration scheitern unterschiedlich“

Statische Integration vermeidet den zusätzlichen Remote-Abruf zur Laufzeit. Der integrierte Stand wird gemeinsam gebaut und als zusammenhängende Anwendung ausgeliefert. Ein Manifest- oder Ladefehler eines separat betriebenen Remote-Artefakts tritt deshalb nicht auf.

Statisch integrierte Bereiche können dennoch zur Laufzeit scheitern. Renderfehler, Exceptions und globale Seiteneffekte benötigen weiterhin eine Begrenzung.

Zugleich betrifft ein fehlerhafter gemeinsamer Build oder Release potenziell die gesamte Anwendung. Der Fehler liegt dann nicht in der Laufzeitaktivierung eines separaten Remotes, sondern im gemeinsam ausgelieferten Stand.

Bei dynamischer Integration kann dagegen ein einzelnes Remote unabhängig nicht erreichbar sein. Netzwerk-, Manifest- und Aktivierungsfehler treten erst zur Laufzeit auf. Die Shell kann diese Zustände erkennen, lokal degradieren und nach einer Korrektur wieder das neu veröffentlichte Remote laden.

Die kleinere Deployment-Einheit kann Auslieferungsfehler stärker begrenzen. Sie ist jedoch weder Voraussetzung noch Garantie für eine kleinere Laufzeit-Fehlerdomäne. Auch statisch integrierte Bereiche können durch bewusst gesetzte Fehlergrenzen voneinander isoliert werden.

Dynamische Integration ermöglicht kleinere Ausfallbereiche. Sie erzeugt sie nicht von selbst.

Beide Integrationsformen benötigen daher Fehlergrenzen. Sie unterscheiden sich vor allem darin, wann und wodurch Fehler sichtbar werden.

Graceful Degradation bedeutet, dass das Produkt kontrolliert auf einen eingeschränkten Zustand zurückfällt. Die ausgefallene Fähigkeit wird nicht notwendigerweise ersetzt.

Ein sinnvoll degradierter Zustand kann:

  • den betroffenen Produktbereich klar markieren,
  • Navigation und andere Remotes verfügbar halten,
  • einen erneuten Ladeversuch anbieten,
  • einen verständlichen Fehlerhinweis zeigen,
  • einen Link zu einer Status- oder Supportseite anbieten,
  • bereits vorhandene Daten als möglicherweise veraltet kennzeichnen,
  • eine sichere Rückkehr ermöglichen.

Er darf dabei nicht so tun, als sei eine Schreiboperation erfolgreich gewesen. Er darf veraltete Daten nicht als aktuell darstellen. Er darf keine fachlichen Entscheidungen improvisieren. Ebenso wenig sollte er ungesicherte Operationen lokal puffern, wenn dafür kein belastbares fachliches und technisches Konzept existiert.

Graceful Degradation erhält das Produkt, nicht zwangsläufig die ausgefallene Fähigkeit.

Ein degradiertes Produkt bleibt verständlich und bedienbar, ohne eine zweite Implementierung der Fachlichkeit vorzutäuschen.

Ein Fallback ist eine alternative Darstellung des Fehlerzustands. Er ist nicht automatisch eine alternative Implementierung des ausgefallenen Produktbereichs.

Rechnungs-Remote nicht verfügbar
├── Navigation bleibt verwendbar
├── übrige Produktbereiche bleiben erreichbar
├── Fehlerzustand wird angezeigt
└── erneuter Versuch ist möglich

Nicht sinnvoll wäre dagegen:

Rechnungs-Remote nicht verfügbar
└── Shell rekonstruiert spontan die Rechnungsfunktion

Ein Fallback ersetzt nicht das Remote. Er verhindert, dass dessen Ausfall die gesamte Anwendung mitreißt.

Der Fallback muss außerdem zum betroffenen Use Case passen. Für einen optionalen Analysebereich kann ein lokaler Hinweis mit Retry ausreichen. Für einen geschäftskritischen Prozess können zusätzliche Statusinformationen, ein Supportweg oder ein alternativer Zugang notwendig sein.

Eine universelle Fehlerkarte ist daher höchstens ein technisches Grundelement. Sie ersetzt nicht die fachliche Gestaltung des Fehlerzustands.

Der Fehlerzustand ist Teil des Produkterlebnisses. Eine Meldung wie „Something went wrong“ erfüllt diese Verantwortung kaum. Sie benennt weder den betroffenen Bereich noch erklärt sie, was weiterhin möglich ist.

Ein guter Fehlerzustand sollte – abhängig vom konkreten Fall – beantworten:

  • Welcher Bereich ist aktuell nicht verfügbar?
  • Sind andere Bereiche weiterhin nutzbar?
  • Kann der Vorgang wiederholt werden?
  • Wurden bereits eingegebene Daten erhalten?
  • Ist die Aktion möglicherweise trotzdem ausgeführt worden?
  • Gibt es einen alternativen Weg?
  • Wann sollte der Support kontaktiert werden?

Nicht jede Frage ist bei jedem Fehler relevant. Entscheidend ist, dass die Darstellung aus Sicht der betroffenen Person gestaltet wird und nicht lediglich den technischen Zustand des Loaders wiedergibt.

Resilienz zeigt sich nicht im perfekten Zustand. Sie zeigt sich darin, wie verständlich das Produkt im schlechten Zustand bleibt.

Ein bewusst degradierter Zustand macht den Fehler sichtbar, ohne die gesamte Anwendung zu blockieren.

Die Grafik stellt einem normalen Produktbereich mit aktivem Remote einen kontrolliert degradierten Zustand mit verständlichem Hinweis, Retry oder Rückkehr und weiterhin nutzbarer Navigation gegenüber.

Schreiboperationen benötigen ehrliche Fehlerzustände

Abschnitt betitelt „Schreiboperationen benötigen ehrliche Fehlerzustände“

Bei lesenden Use Cases ist ein erneuter Versuch häufig relativ unproblematisch. Schlägt das Laden einer Übersicht fehl, kann die Anwendung den Fehler anzeigen und später erneut laden.

Bei Schreiboperationen ist der Zustand schwieriger. Nach einem Timeout oder Verbindungsabbruch kann unklar sein:

  • ob der Request das Backend erreicht hat,
  • ob die Operation bereits ausgeführt wurde,
  • ob nur die Antwort verloren ging,
  • ob ein erneuter Versuch die Aktion doppelt ausführt.

Der Fallback darf deshalb nicht leichtfertig behaupten, die Aktion sei fehlgeschlagen, wenn ihr tatsächlicher Status unbekannt ist.

Ein ehrlicher degradierter Zustand muss – soweit zuverlässig bestimmbar – zwischen „nicht ausgeführt“, „ausgeführt“ und „Status unbekannt“ unterscheiden. Ist diese Unterscheidung nicht möglich, muss genau diese Unsicherheit verständlich kommuniziert werden.

Idempotente Operationen können Wiederholungen sicherer machen. Die Oberfläche darf aus technischer Unklarheit dennoch keine fachliche Gewissheit erzeugen.

Automatische Retries sind bei Schreiboperationen deshalb besonders vorsichtig einzusetzen. Ein unsichtbar wiederholter Lesezugriff ist etwas anderes als eine mehrfach ausgelöste Bestellung, Buchung oder Freigabe.

Ein lokal begrenzter Fehler verbessert das Benutzererlebnis. Betrieblich hilfreich wird er erst, wenn er zugleich beobachtbar bleibt.

Die Plattform sollte technische Informationen erfassen können, etwa:

  • welches Remote betroffen ist,
  • in welcher Lebenszyklusphase der Fehler auftrat,
  • ob Laden, Aktivierung oder Laufzeit betroffen waren,
  • welche Version oder welches Artefakt aktiv war,
  • ob ein Retry erfolgreich war,
  • wie häufig der Fehler auftritt.

Dabei sollten keine personenbezogenen Daten, Tokens oder fachlichen Nutzdaten unnötig protokolliert werden. Gute Diagnose entsteht nicht durch maximale Datensammlung, sondern durch zielgerichtete technische Kontextinformationen.

Benutzerhinweis und technische Diagnose verfolgen unterschiedliche Ziele:

Benutzer
└── erhält verständlichen Produktzustand
Betrieb
└── erhält technische Diagnose

Ein Fallback ohne Beobachtbarkeit schützt die Oberfläche, aber nicht den Betrieb.

Resilienz darf Fehler nicht unsichtbar machen. Sie muss ihre Reichweite begrenzen und ihre Ursachen auffindbar halten.

Ein erneuter Ladeversuch kann bei vorübergehenden Netzwerkfehlern, kurzzeitig nicht erreichbaren Artefakten oder einem fehlgeschlagenen dynamischen Import sinnvoll sein.

Nicht jeder Fehler wird jedoch durch Wiederholung besser. Eine deterministisch fehlschlagende Initialisierung scheitert beim zehnten Versuch meist ebenso wie beim ersten. Wiederholte Mounting-Versuche ohne vorherige Bereinigung können den Zustand zusätzlich verschlechtern.

Zu vermeiden sind insbesondere:

  • unendliche Ladezustände,
  • aggressive automatische Retries,
  • wiederholte Mounting-Versuche ohne Bereinigung,
  • wiederholte Schreiboperationen ohne gesicherte Semantik.

Ein manueller Retry ist häufig verständlicher als eine unsichtbare, unbegrenzte Wiederholung. Er gibt der betroffenen Person Kontrolle und lässt sich mit einem klaren Zustandswechsel verbinden.

Automatische Wiederherstellung kann sinnvoll sein, wenn Fehlerklasse, Begrenzung und Semantik bekannt sind. Ihr Verhalten muss fachlich nachvollziehbar bleiben.

Remotes im selben Dokument teilen einen großen Teil ihrer Laufzeit. Stärkere technische Isolation ist beispielsweise durch getrennte Dokumente oder iFrames möglich.

Dadurch können bestimmte Fehlerwirkungen klarer begrenzt werden. Ein separates Dokument besitzt einen eigenen JavaScript-Kontext und eine deutlichere technische Grenze gegenüber der umgebenden Anwendung.

Diese Isolation bringt jedoch höhere Integrationskosten mit sich – unter anderem bei Navigation, Styling, Barrierefreiheit, Kommunikation, Routing, Authentifizierung und einem konsistenten Produkterlebnis.

Je stärker die technische Isolation, desto klarer können bestimmte Fehlergrenzen werden. Gleichzeitig steigen die Integrationskosten.

Die notwendige Isolation hängt von Kritikalität, akzeptierten Fehlerwirkungen und Integrationskosten ab.

Der Ausfall bleibt beim betroffenen Produktbereich

Abschnitt betitelt „Der Ausfall bleibt beim betroffenen Produktbereich“

Ein tragfähiges Microfrontend besitzt nicht nur eine Deployment-Grenze. Es besitzt auch eine bewusst hergestellte Fehlergrenze.

Kann ein Remote nicht geladen, aktiviert oder weiter ausgeführt werden, bleibt der Fehler auf den betroffenen Produktbereich begrenzt. Die Plattform erhält Navigation und übrige Fähigkeiten. Sie zeigt einen verständlichen degradierten Zustand, ermöglicht eine sichere Rückkehr oder einen kontrollierten Retry und macht den Fehler für den Betrieb beobachtbar.

Ein Microfrontend ist erst dann wirklich unabhängig, wenn auch sein Ausfall eine begrenzte Reichweite besitzt.

Getrennte Deployments erzeugen noch keine getrennten Fehlerbereiche. Die Fehlergrenze entsteht erst durch die kontrollierte Integration am Mounting-Punkt, durch passende Fallbacks und durch eine Produktgestaltung, die den schlechten Zustand ernst nimmt.

Graceful Degradation erhält das Produkt, nicht zwangsläufig die ausgefallene Fähigkeit. Sie ersetzt weder die Fachlichkeit des Remotes noch die Pflicht, den Fehler zu beheben.

Die Shell kann den Ausfall eines Remotes begrenzen. Sie bleibt selbst ein gemeinsamer Ausfallbereich. Gerade deshalb sollte sie stabil, beobachtbar und fachlich möglichst wenig volatil sein.

Der Ausfall eines Remotes darf eine Fähigkeit kosten, aber nicht das gesamte Produkt.

  1. Martin Fowler und James Lewis, „Microservices“ – Design for failure; ergänzend Martin Fowler, „Microservice Trade-Offs“.