How the Circuit Breaker Pattern Prevents Cascading Failures in Microservices

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • MyrinNew
    Senior Member
    • Feb 2024
    • 5175

    #1

    How the Circuit Breaker Pattern Prevents Cascading Failures in Microservices

    Modern microservice architectures improve scalability and team autonomy, but they also introduce a new challenge: service dependency failures.


    If one service becomes slow or unavailable, it can easily cascade across the system, bringing down multiple services.


    This is where the Circuit Breaker Pattern becomes extremely important.


    In this article we will cover:
    • The cascading failure problem
    • How circuit breakers solve it
    • Circuit breaker states
    • A working example using Resilience4j
    • Best practices when using circuit breakers





    The Cascading Failure Problem

    Imagine a simple microservice system:






    Client → Order Service → Payment Service → Database







    Now assume the Payment Service becomes slow or unavailable.


    What happens?

    1. Order service keeps sending requests.
    2. Requests start waiting.
    3. Threads become blocked.
    4. System resources get exhausted.
    5. Eventually the Order Service also crashes.


    This is called a cascading failure.


    A single failure spreads across services.





    The Circuit Breaker Concept

    The concept is inspired by electrical circuit breakers.


    When electrical current becomes dangerous, the circuit breaker cuts the flow to prevent damage.


    Similarly in microservices, a circuit breaker:
    • monitors failures
    • stops sending requests temporarily
    • allows the system to recover


    Instead of continuously calling a failing service, we fail fast.





    Circuit Breaker States

    A circuit breaker typically has three states.


    1️⃣ Closed State





    Client → Order Service → Payment Service
    • Requests flow normally
    • Failures are monitored
    • If failures exceed threshold → state changes


    2️⃣ Open State





    Client → Order Service ✖ Payment Service
    • Calls are blocked immediately.
    • No request is sent to failing service.
    • System return a fallback response.


    3️⃣ Half-Open State





    Client → Order Service → Payment Service (limited test requests)
    • Only a few requests allowed.
    • If they succeed → circuit closes.
    • If they fail → circuit opens again





    Circuit Breaker Flow





    Closed → Failures detected → Open
    Open → Cooldown period → Half-Open
    Half-Open → Success → Closed
    Half-Open → Failure → Open










    Implementing Circuit Breaker using Resilience4j

    One of the most popular circuit breaker libraries in Java is Resilience4j.

    It works very well with Spring Boot.



    Add Dependency





    io.github.resilience4j
    resilience4j-spring-boot3








    Configure Circuit Breaker

    application.yml






    resilience4j:
    circuitbreaker:
    instances:
    paymentService:
    registerHealthIndicator: true
    slidingWindowSize: 10
    minimumNumberOfCalls: 5
    failureRateThreshold: 50
    waitDurationInOpenState: 10s







    Explanation:
    • slidingWindowSize → number of calls monitored
    • failureRateThreshold → percentage to trigger breaker
    • waitDurationInOpenState → time before retry





    Applying Circuit Breaker to a Service

    Example: calling a Payment Service.






    @Service
    public class PaymentClient {

    @CircuitBreaker(name = "paymentService", fallbackMethod = "fallbackPayment")
    public String processPayment() {

    // call external payment service
    return restTemplate.getForObject(
    "http://payment-service/pay",
    String.class
    );
    }

    public String fallbackPayment(Throwable ex) {
    return "Payment service unavailable. Please try later.";
    }
    }







    What happens here:

    1. Calls go normally.
    2. If failure rate exceeds threshold → circuit opens.
    3. All calls go directly to fallback method.





    What a Fallback Response Looks Like

    Fallback responses prevent system crashes.






    {
    "status": "FAILED",
    "message": "Payment service temporarily unavailable"
    }







    Instead of crashing, the system degrades gracefully.





    When Should You Use Circuit Breakers?

    Circuit breakers are useful when:
    • calling external APIs.
    • calling slow microservices.
    • interacting with unreliable networks.


    Typical examples:






    Order Service → Payment Service
    Checkout Service → Inventory Service
    API Gateway → User Service










    When NOT to Use Circuit Breakers

    Avoid using circuit breakers for:
    • database calls inside the same service
    • very fast local operations
    • in-memory calls


    Circuit breakers are best suited for remote network calls.





    Best Practices

    ✔ Always define fallback responses

    ✔ Monitor breaker metrics

    ✔ Combine with retry mechanism

    ✔ Use timeouts with circuit breakers





    Final Thoughts

    Microservices improve scalability and flexibility, but they also introduce reliability challenges when services depend on each other. A failure in one service can quickly propagate and lead to cascading failures across the system.


    The Circuit Breaker Pattern helps prevent this by stopping repeated calls to failing services and allowing systems to fail fast with fallback responses. Tools like Resilience4j make it easy to implement this pattern in Spring Boot applications.


    In the next article, we’ll explore building production-grade resilience using Resilience4j, including retries, bulkheads, and other advanced patterns.


    Stay tuned for the next part of this series 🚀




    More...
Working...