Circuit Breaker Pattern in detail

Circuit Breaker Pattern in detail

The Circuit Breaker Pattern is a design pattern used to detect failures and encapsulate the logic of preventing a failure from constantly recurring during maintenance, temporary external system failure, or unexpected system difficulties. The circuit breaker pattern is particularly useful in microservices architecture where multiple microservices interact with each other.

Circuit Breaker Pattern in detail

How It Works

  • 1. Closed State: Initially, the circuit is in a closed state, meaning requests are flowing normally.
  • 2. Open State: If the failure rate exceeds a certain threshold, the circuit trips to the open state, blocking the requests for a specified period.
  • 3. Half-Open State: After the timeout period, a few trial requests are allowed. If they succeed, the circuit goes back to the closed state; otherwise, it goes back to the open state.

This pattern helps to prevent cascading failures and provides a graceful degradation of service.

Java Example Using Resilience4j

Resilience4j is a lightweight, easy-to-use library inspired by Netflix Hystrix but designed for Java 8 and functional programming.

Here’s an example of implementing the Circuit Breaker Pattern in a Java microservice using Resilience4j:

  • 1. Add Dependencies
    • Add the following dependencies to your `pom.xml`:

Example
   ```xml
   <dependency>
       <groupId>io.github.resilience4j</groupId>
       <artifactId>resilience4j-spring-boot2</artifactId>
       <version>1.7.1</version>
   </dependency>
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-aop</artifactId>
   </dependency>
   ```

  • 2. Configuration
    • Configure the circuit breaker in `application.yml`:

Example
   ```yaml
   resilience4j.circuitbreaker:
     instances:
       backendA:
         registerHealthIndicator: true
         slidingWindowSize: 100
         permittedNumberOfCallsInHalfOpenState: 10
         minimumNumberOfCalls: 10
         waitDurationInOpenState: 10000
         failureRateThreshold: 50
         eventConsumerBufferSize: 10
   ```

  • 3. Service Implementation
    • Implement the service that uses the circuit breaker:

Example
   ```java
   import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
   import org.springframework.stereotype.Service;
   import org.springframework.web.client.RestTemplate;

   @Service
   public class MyService {

       private final RestTemplate restTemplate;

       public MyService(RestTemplate restTemplate) {
           this.restTemplate = restTemplate;
       }

       @CircuitBreaker(name = "backendA", fallbackMethod = "fallback")
       public String callExternalService() {
           return restTemplate.getForObject("http://external-service/api", String.class);
       }

       public String fallback(Exception e) {
           return "Fallback response";
       }
   }
   ```

  • 4. Controller
    • Create a controller to expose the endpoint:

Example
   ```java
   import org.springframework.web.bind.annotation.GetMapping;
   import org.springframework.web.bind.annotation.RestController;

   @RestController
   public class MyController {

       private final MyService myService;

       public MyController(MyService myService) {
           this.myService = myService;
       }

       @GetMapping("/invoke")
       public String invokeService() {
           return myService.callExternalService();
       }
   }
   ```

In this example, when the external service call fails and exceeds the failure threshold, the circuit breaker will open and subsequent calls will go through the fallback method until the circuit breaker resets.