Lexikon · C

Circuit Breaker

Ein Resilienzmuster, das Aufrufe an eine fehlerhafte Abhängigkeit zeitweise stoppt, statt Fehler weiterzureichen.

Von Obseria-RedaktionAktualisiert

Definition

Ein Circuit Breaker ist ein Resilienzmuster, das Aufrufe an eine entfernte Abhängigkeit kapselt und keine Anfragen mehr sendet, wenn Fehler oder langsame Aufrufe einen Schwellwert überschreiten. Er wechselt zwischen drei Zuständen: Closed (Aufrufe laufen durch), Open (Aufrufe scheitern sofort) und Half-Open (einige Testaufrufe prüfen die Erholung).

Was ein Circuit Breaker ist

Ein Circuit Breaker schützt einen Service vor einer Abhängigkeit, die ausfällt oder nur noch langsam antwortet. Ohne ihn senden alle Aufrufer weiter Anfragen, warten auf Timeouts und blockieren Threads, Verbindungen und Speicher. Die Langsamkeit wandert nach oben, bis auch Services ohne eigenen Defekt keine Kapazität mehr haben: ein Kaskadenfehler. Das Muster wurde durch Michael Nygards Buch Release It! bekannt und ist nach der elektrischen Sicherung benannt, die den Strom trennt, bevor Leitungen überhitzen.

Der Breaker sitzt im Client, etwa in einer Bibliothek wie Resilience4j (Java) oder Polly (.NET), oder in der Netzwerkschicht, zum Beispiel im Proxy eines Service Mesh wie Envoy.

Die drei Zustände: Closed, Open, Half-Open

ZustandVerhaltenÜbergang
ClosedAufrufe laufen durch, Ergebnisse werden in einem gleitenden Fenster erfasst.Öffnet, wenn Fehler- oder Slow-Call-Rate den Schwellwert überschreitet.
OpenAufrufe werden sofort abgewiesen, meist mit Fallback.Wechselt nach einer festgelegten Wartezeit zu Half-Open.
Half-OpenEine begrenzte Zahl von Testaufrufen ist erlaubt.Schließt bei Erfolg, öffnet bei erneuten Fehlern wieder.

Der wichtigste Nutzen des Open-Zustands ist Fail Fast: Der Aufrufer erhält in Mikrosekunden eine Antwort, statt auf einen Timeout zu warten, und die angeschlagene Abhängigkeit bekommt Luft zur Erholung, statt von Retries überrollt zu werden.

Beispielkonfiguration

Eine beispielhafte Resilience4j-Konfiguration für einen Payment-Client:

resilience4j.circuitbreaker:
  instances:
    payments:
      slidingWindowType: COUNT_BASED
      slidingWindowSize: 50
      minimumNumberOfCalls: 20
      failureRateThreshold: 50
      slowCallDurationThreshold: 2s
      slowCallRateThreshold: 80
      waitDurationInOpenState: 30s
      permittedNumberOfCallsInHalfOpenState: 5

Gelesen heißt das: Die letzten 50 Aufrufe auswerten, aber erst ab mindestens 20 Aufrufen. Der Breaker öffnet, wenn die Hälfte scheitert oder 80 % länger als zwei Sekunden dauern. Er bleibt 30 Sekunden offen, danach entscheiden fünf Testaufrufe. Die Mindestanzahl verhindert, dass ein einzelner Fehler bei wenig Traffic den Breaker auslöst.

Warum das für Observability wichtig ist

Circuit Breaker verändern, was Ihre Telemetrie zeigt. Solange ein Breaker offen ist, wirkt der nachgelagerte Service gesund und ruhig, weil er keinen Traffic erhält, während der Aufrufer einen Anstieg abgewiesener Aufrufe meldet. Bei der Incident-Analyse brauchen Sie beide Seiten: den Zustand des Breakers, die Zahl der Abweisungen und die ursprüngliche Fehlerrate oder Latenz, die ihn ausgelöst hat. Nützliche Signale sind:

  • Zustand pro Instanz und Abhängigkeit, als Gauge oder als Zustandswechsel-Event.
  • Aufrufe nach Ergebnis: erfolgreich, fehlgeschlagen, langsam, abgewiesen.
  • Fehler- und Slow-Call-Raten im Vergleich zu den konfigurierten Schwellwerten.
  • Fallback-Ausführungen, die Fehler vor Nutzern verbergen, aber trotzdem eingeschränkten Service bedeuten.

Markieren Sie in Distributed Traces kurzgeschlossene Spans, etwa mit einem Attribut oder Span-Event, damit eine schnelle Abweisung nicht als gesunder Aufruf erscheint.

Circuit Breaking im Service Mesh

Proxies wie Envoy setzen die Idee anders um als Client-Bibliotheken. Die „Circuit Breaker“ von Envoy sind Obergrenzen für gleichzeitige Verbindungen, wartende Anfragen, aktive Anfragen und Retries pro Upstream-Cluster: Ist eine Grenze erreicht, werden weitere Anfragen sofort abgewiesen. Das Aussortieren einzelner fehlerhafter Hosts übernimmt die Outlier Detection. Sie entfernt einen Endpunkt aus dem Load-Balancing-Pool, etwa nach mehreren aufeinanderfolgenden 5xx-Antworten, und nimmt ihn nach einer Sperrzeit wieder auf. In Istio konfigurieren Sie beides in einer DestinationRule über connectionPool und outlierDetection. Der Mesh-Ansatz kommt ohne Codeänderungen aus und wirkt einheitlich über alle Programmiersprachen hinweg. Bibliotheken kennen dagegen die Semantik der Anwendung besser, etwa welche Exceptions als Fehler zählen sollen und welcher Fallback sinnvoll ist. In der Praxis kombinieren viele Teams beide Ebenen: Das Mesh begrenzt Last und sortiert defekte Instanzen aus, die Bibliothek entscheidet über fachlich sinnvolle Fallbacks.

Best Practices

  • Mit Timeouts kombinieren. Ein Breaker erkennt langsame Aufrufe nur, wenn Aufrufe überhaupt einen Timeout haben.
  • Vorsichtig wiederholen. Retries gehören in das Budget des Breakers und brauchen exponentiellen Backoff mit Jitter, sonst halten sie den Breaker dauerhaft offen.
  • Pro Abhängigkeit trennen. Ein Breaker je nachgelagertem Service oder Endpunkt, nicht einer für den gesamten ausgehenden Traffic.
  • Fallback bewusst gestalten. Gecachte Daten, ein Standardwert oder eine klare Fehlermeldung, je nach Anwendungsfall.
  • Auf Zustandswechsel alarmieren. Ein offener Breaker ist ein frühes und präzises Signal für Probleme einer Abhängigkeit.

Typische Fehler

Häufig werden Schwellwerte aus Beispielen übernommen, ohne sie unter Last zu testen. Breaker öffnen nie, weil Fehler verschluckt und als HTTP 200 zurückgegeben werden, oder Fallbacks liefern stundenlang veraltete Daten, ohne dass es jemand bemerkt. Eine weitere Falle: Client-Fehler wie HTTP 400 als Fehlschlag zu zählen, sodass ein einzelner fehlerhafter Aufrufer den Breaker für alle öffnet.

Wie Obseria unterstützt

Obseria verknüpft abgewiesene und fehlgeschlagene Spans des Aufrufers mit der Telemetrie des nachgelagerten Service in einer Trace-Ansicht, und Obseria TopoGraph zeigt, welche Services von der betroffenen Komponente abhängen. Über OpenTelemetry oder Prometheus exportierte Breaker-Metriken können Alerts auslösen, und Fehler-Tracking gruppiert die Exceptions, die den Breaker ausgelöst haben.

Häufig gestellte Fragen

Nach Ablauf der Wartezeit im Open-Zustand lässt der Breaker einige Testaufrufe zu. Gelingen sie, schließt er und der normale Traffic läuft wieder; scheitern sie, öffnet er erneut. So wird eine sich erholende Abhängigkeit nicht schlagartig überlastet.

Ein Retry wiederholt einen fehlgeschlagenen Aufruf in der Hoffnung auf einen vorübergehenden Fehler. Ein Circuit Breaker stoppt Aufrufe an eine dauerhaft fehlerhafte Abhängigkeit. Beide ergänzen sich: Retries fangen kurze Störungen ab, der Breaker verhindert, dass Retries einen echten Ausfall verschlimmern.

Netflix hat Hystrix 2018 in den Wartungsmodus versetzt und auf Alternativen verwiesen. Für Java ist heute Resilience4j verbreitet, .NET-Teams nutzen oft Polly, und Service Meshes bieten Circuit Breaking auf Proxy-Ebene.

Erfassen Sie den Zustand, Zustandswechsel, Aufrufe nach Ergebnis (Erfolg, Fehler, langsam, abgewiesen), Fehler- und Slow-Call-Raten im Vergleich zu den Schwellwerten sowie Fallback-Ausführungen. Alarmieren Sie, wenn ein Breaker öffnet oder wiederholt flattert.

Setzen Sie das Wissen in die Praxis um

Testen Sie Obseria 14 Tage kostenlos, mit OpenTelemetry und ohne proprietäre Agenten.