• Skip to main content
  • Skip to secondary menu
  • Skip to primary sidebar
  • Skip to footer
  • Home
  • Contact Us

All about code

  • Java
    • Spring
      • Spring Boot
      • Spring Cloud
    • Java Miscellaneous Tips
    • Java Design Patterns
  • Data Structures and Algorithms
    • Algorithms
    • Data Structures
  • Thoughts and Stories
  • AI

How to Implement Circuit Breaker Pattern With Spring Cloud

laptop digital device technology 5673901

Introduction

Circuit Breaker is an important feature of micro-service systems. The whole system could be highly affected if one or more services are unavailable. Circuit breaking alleviates these issues by avoiding calling services while they are down. In this article, you will learn how to integrate this feature into a Spring Boot project using the Resilience4j package available in Spring Cloud.

Circuit Breaker Pattern

The circuit breaker pattern is based on three states: closed, open and half-open. We will briefly describe them.

Closed State

If we consider two interacting services, one calling the other, this is the state when both are up and functioning correctly. Circuit breaker implementation will keep checking the health of the called service, counting the number of failed calls, and eventually triggering a state change based on a configured threshold.

Open State

If the threshold is reached, the state changes to open. The call will then be bypassed by returning an exception (or another convenient result, if configured).

Half-open State

When a predefined time range is passed from the last open state, the state changes to half open. In this state, a limited number of calls is allowed: if the failing rate is still above the threshold it returns to open, otherwise it changes to closed.

Spring Cloud Circuit Breaker Abstraction

Spring Cloud abstracts the way to approach circuit breaking using a pluggable architecture. The developer is free to choose which implementation to use. The following are supported:

  • Resilience4J
  • Spring Retry

Using one or the other in a Spring Boot project is just a matter of setting a specific dependency. If we want to use Resilience4J in our project we need to set the spring-cloud-starter-circuitbreaker-resilience4j starter, after having defined the Spring Cloud release train in the dependency management section:

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>2023.0.0</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>		

       <dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
		</dependency>

When Spring Boot detects the presence of the Resilience4j package in the classpath, it activates its autoconfiguration features, with a set of defaults.

Resilience4j Features

Resilience4j is a library aimed at improving the fault tolerance of micro-service systems. Besides the circuit breaker functionality, It offers several other features:

  • Circuit breaker: deals with remote not responding services by-passing the faulting calls
  • Retry: implements a retry mechanism for the failing requests
  • Time limiter: set a time limit for remote calls
  • Rate limiter: set a limit to the number of requests in a given time
  • Bulkhead: set a limit to the number of concurrent requests

Resilience4j Circuit Breaker Configuration

We have to edit the application.yaml file to configure the circuit breaker functionality in a Spring Boot application. This is an example:

resilience4j:
  circuitbreaker:
    instances:
      CircuitBreakerApi:
        sliding-window-size: '10'
        sliding-window-type: count_based
        failure-rate-threshold: '50'
        minimum-number-of-calls: '5'
        permitted-number-of-calls-in-half-open-state: '3'
        wait-duration-in-open-state: 5s
        automatic-transition-from-open-to-half-open-enabled: 'true'

We can define one or more instances with a given name (‘CircuitBreakerApi’ in the above example). That name can then be used to apply the feature to endpoints by a specific annotation.

sliding-window-size

It defines the size of a sliding window that constitutes a sample of the call outcomes. The circuit breaker uses this sample as a base to calculate the failure rate of an endpoint. There are two types of sliding windows, the count-based type and the time-based type. In the count-based type, the sliding window is implemented as a circular array with a size equal to sliding-window-size: each time a new call outcome is stored in the array, the oldest one is evicted.

In the time-based approach, the sliding window size is defined in seconds. In this case, the circular array represents a set of buckets. If the size is 10 seconds, we thus have 10 buckets, one bucket for each second in a consecutive interval of time in which the measurements are made. Each bucket stores the outcomes of all the calls made in a particular second in the time interval.

failure-rate-threshold

It defines the percentage of failed calls in a sliding window that makes the circuit breaker stop further requests.

minimum-number-of-calls

It represents the minimum number of failed calls that can be used in a sliding window to calculate the failure percentage.

permitted-number-of-calls-in-half-open-state

It’s the maximum number of calls in a half-open state. After that number, the state will pass to open it if those calls fail, otherwise it will pass to closed.

wait-duration-in-open-state

Time interval before going to half-open from the open state.

automatic-transition-from-open-to-half-open-enabled

If set to true, it automatically triggers the transition to the half-open state, where the wait-duration-in-open-state time interval is passed. If set to false, it triggers the transition only if the time interval is passed and a call is made (this avoids the need for a monitoring thread).

Resilience4j Other Features Configuration

In this article, we will cover only the circuit breaker, but just to complete the picture, we show here an example of the configuration of the other features:

resilience4j:
  retry:
    instances:
      RetryApi:
        max-attempts: '3'
        wait-duration: 1s
  timelimiter:
    instances:
      TimeLimiterApi:
        timeout-duration: 2s
        cancel-running-future: 'true'
  bulkhead:
    instances:
      BulkheadApi:
        max-wait-duration: '1'
        max-concurrent-calls: '3'
  ratelimiter:
    instances:
      RateLimiterApi:
        timeout-duration: 0s
        event-consumer-buffer-size: '50'
        register-health-indicator: 'true'
        limit-for-period: '5'
        subscribe-for-events: 'true'
        limit-refresh-period: 60s
        allow-health-indicator-to-fail: 'true'

Testing Circuit Breaker

We will demonstrate how a Resilience4j circuit breaker works by using a Junit Test and two simple Spring Boot services. You can find the example in the link at the bottom of this article. The client component is meant to represent a book service of a library software that calls an author service to retrieve information about specific authors. For this test, the client service will expose a /getAuthorServiceInstance endpoint that, in turn, will remotely call a /getInstance endpoint that serves the sole purpose of pinging the server, returning a string with the service server name and port.

The example uses the following versions of Java, Spring Boot, and Spring Cloud:

  • Spring Boot: 3.2.1
  • Spring Cloud: 2023.0.0
  • Java 17

The configuration application.xml file for the test environment contains the following settings:

resilience4j:
  circuitbreaker:
    instances:
      CircuitBreakerApi:
        sliding-window-size: '10'
        minimum-number-of-calls: '5'
        permitted-number-of-calls-in-half-open-state: '3'
        failure-rate-threshold: '50'
        wait-duration-in-open-state: 5s
        sliding-window-type: count_based
        automatic-transition-from-open-to-half-open-enabled: 'true'

The controller method of the client endpoint is annotated with the @CircuitBreaker annotation, using the instance name “CircuitBreakerApi”:

    @GetMapping(value = "/getAuthorServiceInstance")
    @CircuitBreaker(name = "CircuitBreakerApi", fallbackMethod = "getAuthorServiceInstanceFallback")
    public String getAuthorServiceInstance() {
        return bookService.getAuthorServiceInstance();
    }

The annotation above defines a fallback method returning a simple string, which will be executed when the state is open, in place of the original call:

    public String getAuthorServiceInstanceFallback(Exception ex) {
        return "Fallback content";
    }

We mock the /authors/getInstance service by using the WireMockExtension class and make it return a server error. We then execute a for loop with five calls to the /getAuthorServiceInstance client endpoint using a TesRestTemplate class instance. At each step, we will check the circuit breaker state using the instance obtained from the circuit breaker registry.

Since we have set the minimum-number-of-calls parameter to 5, we expect it will change the status from closed to open only at the fifth call. Then, if we continue to call the service, we expect the status to change from open to half-open and vice versa since the service is always down. You can see the test implementation in the following code snippet:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
class CircuitBreakerTest {

    @RegisterExtension
    static WireMockExtension mockService = WireMockExtension.newInstance()
        .options(WireMockConfiguration.wireMockConfig()
            .port(8091))
        .build();

    @Autowired
    private TestRestTemplate restTemplate;

    @Autowired
    private CircuitBreakerRegistry circuitBreakerRegistry;

    @Test
    public void testCircuitBreaker() {
        mockService.stubFor(WireMock.get("/authors/getInstance")
            .willReturn(serverError()));

        Optional<CircuitBreaker> circuitBreakerOptional = circuitBreakerRegistry.getAllCircuitBreakers()
            .stream()
            .findFirst();
        CircuitBreaker circuitBreaker = circuitBreakerOptional.get();

        for (int i = 0; i < 5; i++) {
            restTemplate.getForEntity("http://localhost:8080/library/getAuthorServiceInstance", String.class);
            if (i < 4) {
                assertTrue(circuitBreaker.getState()
                    .equals(CircuitBreaker.State.CLOSED));
            } else {
                assertTrue(circuitBreaker.getState()
                    .equals(CircuitBreaker.State.OPEN));
            }
        }

        for (int i = 0; i < 5; i++) {
            restTemplate.getForEntity("http://localhost:8080/library/getAuthorServiceInstance", String.class);
            assertTrue(circuitBreaker.getState()
                .equals(CircuitBreaker.State.OPEN) || circuitBreaker.getState()
                    .equals(CircuitBreaker.State.HALF_OPEN));
        }

    }

}

Conclusion

The circuit breaker pattern is essential in microservice systems. It allows us to minimize the impact of specific node failures on the whole system. Resilience4j, among other useful features, provides an implementation for this pattern that can be easily plugged into Spring Boot, using the Spring Cloud circuit breaker abstraction.

You can find the source code of the example in this article on GitHub.

Primary Sidebar

Social

  • Facebook
  • LinkedIn
  • Twitter

Archives

  • May 2026
  • April 2026
  • March 2026
  • August 2025
  • July 2025
  • June 2025
  • May 2025
  • April 2025
  • March 2025
  • December 2024
  • October 2024
  • August 2024
  • July 2024
  • March 2024
  • February 2024
  • January 2024
  • December 2023
  • September 2023
  • May 2023
  • March 2023
  • January 2023
  • November 2022
  • September 2022
  • August 2022

Recent Posts

  • Better Avoid Spring Boot Lazy-initialization @PostConstruct Trap
  • How To Handle Large Datasets in Spring Boot
  • How to Log HTTP Incoming Requests in Spring Boot
  • How to Reliably Implement Post-Commit Actions in Spring
  • Brief and Easy Explanation of HATEOAS

TAGS

Algorithms Apache POI Backtracking Date Structures Dynamic Programming engineering Graphs Greedy Horror Stories HSSF Java Java New Features Java Principles Java tips real life Sorting Spring Boot Spring Cloud Strings Trees

Footer

Privacy Policy Cookie Policy Terms and Conditions