Deutsch

Entdecken Sie das Circuit-Breaker-Muster für Fehlertoleranz, um die Ausfallsicherheit und Stabilität von Anwendungen zu verbessern. Lernen Sie seine Implementierung, Vorteile und Praxisbeispiele aus verschiedenen Branchen und globalen Kontexten kennen.

Circuit Breaker: Ein robustes Fehlertoleranzmuster für moderne Anwendungen

Im Bereich der Softwareentwicklung, insbesondere bei Microservices-Architekturen und verteilten Systemen, ist die Gewährleistung der Anwendungsresilienz von größter Bedeutung. Wenn Komponenten ausfallen, ist es entscheidend, kaskadierende Ausfälle zu verhindern und eine stabile, reaktionsschnelle Benutzererfahrung aufrechtzuerhalten. Das Circuit-Breaker-Muster erweist sich als eine leistungsstarke Lösung, um in solchen Szenarien Fehlertoleranz und eine kontrollierte Leistungsreduzierung (graceful degradation) zu erreichen.

Was ist das Circuit-Breaker-Muster?

Das Circuit-Breaker-Muster ist von elektrischen Sicherungsautomaten inspiriert, die Stromkreise vor Schäden durch Überstrom schützen. In der Software fungiert es als Proxy für Operationen, die fehlschlagen könnten, und verhindert, dass eine Anwendung wiederholt versucht, eine Operation auszuführen, die wahrscheinlich fehlschlagen wird. Dieser proaktive Ansatz vermeidet die Verschwendung von Ressourcen, reduziert die Latenz und verbessert letztendlich die Systemstabilität.

Die Kernidee ist, dass, wenn ein Dienst konstant nicht antwortet, der Circuit Breaker "öffnet" und weitere Anfragen an diesen Dienst verhindert. Nach einer definierten Zeitspanne geht der Circuit Breaker in einen "halb-offenen" Zustand über und lässt eine begrenzte Anzahl von Testanfragen durch. Wenn diese Anfragen erfolgreich sind, "schließt" der Circuit Breaker und der normale Betrieb wird wieder aufgenommen. Schlagen sie fehl, bleibt der Circuit Breaker geöffnet und der Zyklus wiederholt sich.

Zustände des Circuit Breakers

Der Circuit Breaker arbeitet in drei verschiedenen Zuständen:

Vorteile der Verwendung des Circuit-Breaker-Musters

Die Implementierung des Circuit-Breaker-Musters bietet mehrere wesentliche Vorteile:

Überlegungen zur Implementierung

Die effektive Implementierung des Circuit-Breaker-Musters erfordert die sorgfältige Berücksichtigung mehrerer Faktoren:

Implementierungsbeispiele

Das Circuit-Breaker-Muster kann mit verschiedenen Programmiersprachen und Frameworks implementiert werden. Hier sind einige Beispiele:

Java mit Resilience4j

Resilience4j ist eine beliebte Java-Bibliothek, die eine umfassende Suite von Fehlertoleranz-Tools bietet, einschließlich Circuit Breaker, Retry, Rate Limiter und Bulkhead. Hier ist ein einfaches Beispiel:


CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()
    .failureRateThreshold(50)
    .waitDurationInOpenState(Duration.ofMillis(1000))
    .permittedNumberOfCallsInHalfOpenState(2)
    .slidingWindowSize(10)
    .build();

CircuitBreaker circuitBreaker = CircuitBreaker.of("myService", circuitBreakerConfig);

Supplier<String> decoratedSupplier = CircuitBreaker
    .decorateSupplier(circuitBreaker, () -> myRemoteService.getData());

try {
    String result = decoratedSupplier.get();
    // Verarbeite das Ergebnis
} catch (RequestNotPermitted e) {
    // Behandle den offenen Zustand des Circuit Breakers
    System.err.println("Circuit ist offen: " + e.getMessage());
}

Python mit Pybreaker

Pybreaker ist eine Python-Bibliothek, die eine einfache und benutzerfreundliche Circuit-Breaker-Implementierung bietet.


import pybreaker

breaker = pybreaker.CircuitBreaker(fail_max=3, reset_timeout=10)

@breaker
def unreliable_function():
    # Ihr unzuverlässiger Funktionsaufruf hier
    pass

try:
    unreliable_function()
except pybreaker.CircuitBreakerError:
    print("Circuit Breaker ist offen!")

.NET mit Polly

Polly ist eine .NET-Bibliothek für Resilienz und die Behandlung von vorübergehenden Fehlern, die es Entwicklern ermöglicht, Richtlinien wie Retry, Circuit Breaker, Timeout und Bulkhead auf eine flüssige und zusammensetzbare Weise auszudrücken.


var circuitBreakerPolicy = Policy
    .Handle<Exception>()
    .CircuitBreakerAsync(
        exceptionsAllowedBeforeBreaking: 3,
        durationOfBreak: TimeSpan.FromSeconds(10),
        onBreak: (exception, timespan) =>
        {
            Console.WriteLine("Circuit Breaker geöffnet: " + exception.Message);
        },
        onReset: () =>
        {
            Console.WriteLine("Circuit Breaker zurückgesetzt.");
        },
        onHalfOpen: () =>
        {
            Console.WriteLine("Circuit Breaker halb-geöffnet.");
        });


try
{
    await circuitBreakerPolicy.ExecuteAsync(async () =>
    {
        // Ihre unzuverlässige Operation hier
        await MyRemoteService.GetDataAsync();
    });
}
catch (Exception ex)
{
    Console.WriteLine("Ausnahme behandelt: " + ex.Message);
}

Praxisbeispiele

Das Circuit-Breaker-Muster wird in verschiedenen Branchen und Anwendungen weit verbreitet eingesetzt:

Circuit Breaker vs. Retry-Muster

Obwohl sowohl das Circuit-Breaker- als auch das Retry-Muster zur Fehlertoleranz verwendet werden, dienen sie unterschiedlichen Zwecken.

In einigen Fällen können diese Muster zusammen verwendet werden. Sie könnten beispielsweise ein Retry-Muster innerhalb eines Circuit Breakers implementieren. Der Circuit Breaker würde übermäßige Wiederholungsversuche verhindern, wenn der Dienst konstant ausfällt, während das Retry-Muster vorübergehende Fehler behandelt, bevor der Circuit Breaker ausgelöst wird.

Zu vermeidende Anti-Muster

Obwohl der Circuit Breaker ein leistungsstarkes Werkzeug ist, ist es wichtig, sich potenzieller Anti-Muster bewusst zu sein:

Fortgeschrittene Konzepte

Fazit

Das Circuit-Breaker-Muster ist ein unverzichtbares Werkzeug für die Erstellung resilienter und fehlertoleranter Anwendungen, insbesondere in Microservices-Architekturen und verteilten Systemen. Indem es kaskadierende Ausfälle verhindert, die Latenz reduziert und eine kontrollierte Leistungsreduzierung ermöglicht, verbessert es die Stabilität der Anwendung und die Benutzererfahrung. Durch sorgfältige Berücksichtigung von Implementierungsdetails und die Vermeidung gängiger Anti-Muster können Sie das Circuit-Breaker-Muster effektiv nutzen, um robustere und zuverlässigere Softwaresysteme zu erstellen. Seine globale Anwendbarkeit macht es zu einer wichtigen Überlegung für jede Anwendung, die für eine vielfältige und internationale Benutzerbasis konzipiert ist. Das Verstehen und Implementieren des Circuit-Breaker-Musters ist für moderne Softwareentwicklungspraktiken von entscheidender Bedeutung. Durch proaktives Angehen potenzieller Ausfälle können Entwickler Systeme bauen, die besser gerüstet sind, um die unvermeidlichen Herausforderungen des verteilten Rechnens zu bewältigen.