Microservices Communication Patterns (Saga, Circuit Breaker) · Leçon

Coupe-circuit et logique de nouvelle tentative

Comprenez l’interaction entre les coupe-circuits et les mécanismes de nouvelle tentative pour optimiser la gestion et la récupération après erreur.

Leçon 2 sur 411 étapes

Coupe-circuit et logique de nouvelle tentative est une leçon Microservices Communication Patterns (Saga, Circuit Breaker) gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Microservices Communication Patterns (Saga, Circuit Breaker), et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Microservices Communication Patterns (Saga, Circuit Breaker) comprend 4 leçons au total.

Certaines parties de cette leçon n'ont pas encore été traduites et s'affichent en anglais.

Combining Circuit Breaker & Retry

In distributed systems, failures are inevitable. We've learned about the Retry Pattern for transient issues and the Circuit Breaker for persistent ones.

But how do these powerful patterns work together? Combining them effectively is key to building truly resilient microservices.

Recap: The Retry Pattern

The Retry Pattern automatically re-attempts an operation that has failed due to a temporary, transient error.

  • Use case: Network glitches, temporary service unavailability, database deadlocks.
  • Goal: Overcome momentary hiccups without user intervention.
  • Mechanism: Usually involves a delay between retries (e.g., exponential backoff).

Recap: The Circuit Breaker

A Circuit Breaker prevents an application from repeatedly invoking a service that is likely to fail. It "trips" the circuit to stop calls when too many errors occur.

  • Use case: Service is down, overloaded, or consistently returning errors.
  • Goal: Fail fast, prevent cascading failures, give the failing service time to recover.
  • States: Closed, Open, Half-Open.

Synergy: CB and Retry

Imagine a service experiencing a brief network blip. Retry can handle this gracefully. But what if the service is completely offline for an extended period?

Without a Circuit Breaker, retries would continuously hammer the unresponsive service, wasting resources and prolonging the problem. This is where their combined power shines!

Order of Operations

When combining these patterns, a critical design decision is: which one wraps the other?

Does the Retry Pattern wrap the Circuit Breaker, or does the Circuit Breaker wrap the Retry Pattern?

The order significantly impacts how your system responds to different types of failures.

Retry Wrapping Circuit Breaker

If the Retry Pattern wraps the Circuit Breaker:

  • Retry attempts the operation.
  • The Circuit Breaker is engaged.
  • If the CB opens, the first attempt fails, and retry might try again, hitting the already open CB.
  • This can lead to retries hitting a fast-failing CB, not allowing the CB to fully protect the system initially.

This setup is generally less effective.

Circuit Breaker Wrapping Retry

If the Circuit Breaker wraps the Retry Pattern:

  • The Circuit Breaker monitors the entire retry operation.
  • If the initial call fails, retry attempts again.
  • Only if all retries fail within the configured attempts, does the Circuit Breaker count it as a single failure.
  • If enough such "all-retry-failed" attempts occur, the CB opens.

This is the recommended approach.

CB Protecting Retry Logic

Here's a conceptual Java example showing how a Circuit Breaker would wrap an operation that includes retry logic. Notice the Circuit Breaker's decision to open or close is based on the final outcome of the retried call.

Try running this example:

import java.util.concurrent.atomic.AtomicInteger;

public class Main {
    // Simulate a dependency that sometimes fails
    private static AtomicInteger serviceCallCount = new AtomicInteger(0);

    public static boolean unreliableServiceCall() {
        System.out.println("  Attempting service call...");
        int currentCount = serviceCallCount.incrementAndGet();
        if (currentCount % 3 == 0) { // Fails every 3rd call
            System.out.println("  Service call FAILED temporarily.");
            return false;
        }
        System.out.println("  Service call SUCCESS.");
        return true;
    }

    public static boolean executeWithRetry() {
        int maxRetries = 2;
        long delayMillis = 100;
        for (int i = 0; i <= maxRetries; i++) {
            try {
                if (unreliableServiceCall()) {
                    return true; // Success after retry
                }
            } catch (Exception e) {
                // Log exception, continue retry
            }
            if (i < maxRetries) {
                System.out.println("  Retrying in " + delayMillis + "ms...");
                try { Thread.sleep(delayMillis); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
            }
        }
        return false; // All retries failed
    }

    // Conceptual Circuit Breaker logic for demonstration
    private static boolean circuitOpen = false;
    private static int failureCount = 0;
    private static final int FAILURE_THRESHOLD = 2; // Open after 2 consecutive failures
    private static final long RESET_TIMEOUT_MILLIS = 500; // Try to close after 0.5s
    private static long lastFailureTime = 0;

    public static boolean executeWithCircuitBreakerAndRetry() {
        if (circuitOpen) {
            if (System.currentTimeMillis() - lastFailureTime > RESET_TIMEOUT_MILLIS) {
                System.out.println("Circuit Breaker: Attempting HALF-OPEN state...");
                circuitOpen = false; // Move to half-open (for demo, just close)
                failureCount = 0; // Reset count
            } else {
                System.out.println("Circuit Breaker: OPEN! Failing fast.");
                return false; // Fail fast if open
            }
        }

        boolean success = executeWithRetry(); // Execute the retry logic

        if (!success) {
            failureCount++;
            lastFailureTime = System.currentTimeMillis();
            if (failureCount >= FAILURE_THRESHOLD) {
                circuitOpen = true;
                System.out.println("Circuit Breaker: OPENED due to repeated failures!");
            } else {
                System.out.println("Circuit Breaker: Failure detected, count=" + failureCount);
            }
        } else {
            failureCount = 0; // Reset failure count on success
            System.out.println("Circuit Breaker: Success, failure count reset.");
        }
        return success;
    }

    public static void main(String[] args) {
        System.out.println("--- Scenario: CB wrapping Retry ---");
        for (int i = 0; i < 7; i++) { // Simulate multiple requests
            System.out.println("\nRequest " + (i + 1) + ":");
            boolean overallSuccess = executeWithCircuitBreakerAndRetry();
            System.out.println("Overall result for Request " + (i + 1) + ": " + (overallSuccess ? "SUCCESS" : "FAILURE"));
            try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
        }
    }
}

Why This Order is Best

Placing the Circuit Breaker around the Retry Pattern offers several advantages:

  • Efficient Failure Detection: The CB only opens after a series of genuinely failed operations (i.e., all retries failed), distinguishing transient issues from persistent outages.
  • Reduced Load: Once the CB is open, it prevents any further retry attempts, protecting the downstream service from being overwhelmed during a prolonged failure.
  • Faster Failures: When the service is truly down, the CB opens quickly, allowing your application to fail fast instead of waiting for all retries to exhaust.

Check Your Understanding

Consider a microservice that experiences intermittent network glitches (transient failures) and occasionally goes completely offline for maintenance (persistent failures).

You are implementing both the Retry Pattern and the Circuit Breaker Pattern to handle these scenarios. Which setup is generally recommended for optimal resilience?

Lesson Summary

We've explored the powerful synergy between the Circuit Breaker and Retry Patterns. While both enhance resilience, their combined effectiveness hinges on their interaction.

Remember, the best practice is to have the Circuit Breaker wrap the Retry Pattern. This allows retries to handle transient faults, while the Circuit Breaker steps in to protect against persistent failures, preventing cascading issues and improving overall system stability.

Keep building robust systems!

Gratuit pour commencer

Apprends Microservices Communication Patterns (Saga, Circuit Breaker) avec un tuteur IA — gratuit

Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.

Cours
12
Leçons
48

Questions Fréquemment Posées

La leçon « Coupe-circuit et logique de nouvelle tentative » est-elle gratuite ?

Oui — le texte complet de « Coupe-circuit et logique de nouvelle tentative » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Microservices Communication Patterns (Saga, Circuit Breaker), passe à CoddyKit PRO. Le cours Microservices Communication Patterns (Saga, Circuit Breaker) comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Coupe-circuit et logique de nouvelle tentative » ?

Comprenez l’interaction entre les coupe-circuits et les mécanismes de nouvelle tentative pour optimiser la gestion et la récupération après erreur. Tu pratiques Microservices Communication Patterns (Saga, Circuit Breaker) avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Microservices Communication Patterns (Saga, Circuit Breaker) ?

Aucune expérience préalable n'est requise. Microservices Communication Patterns (Saga, Circuit Breaker) sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.

Combien de temps prend la leçon « Coupe-circuit et logique de nouvelle tentative » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Microservices Communication Patterns (Saga, Circuit Breaker) ?

Oui. Chaque leçon Microservices Communication Patterns (Saga, Circuit Breaker) inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Coupe-circuit et cloisonnement
  2. Coupe-circuit et logique de nouvelle tentative
  3. Intégration de la limitation du débit
  4. Ordre des décorateurs de résilience
← Retour à Microservices Communication Patterns (Saga, Circuit Breaker)