How to use circuit breaker based on a method parameter?

543 views Asked by At

I have a http client that connects to the same api endpoint on different servers. Which server it connects to, depends on business logic.

Let's say the http client method is connect(url). How can I make sure that the circuit breaker takes the url into account? If my http client sends requests to both url_A and url_B , and server A goes down, then I want that my http client can still send requests to server B.

Does Failsafe or Resilience4J support this out-of-the-box?

1

There are 1 answers

2
Raghvendra Garg On

Assuming that all your CircuitBreakers will use the same configuration. you can create a global config like below.

public CircuitBreakerConfig defaultConfig(){
    return CircuitBreakerConfig.custom()
          .failureRateThreshold(50)
          .slowCallRateThreshold(50)
          .waitDurationInOpenState(Duration.ofMillis(1000))
          .slowCallDurationThreshold(Duration.ofSeconds(2))
          .permittedNumberOfCallsInHalfOpenState(3)
          .minimumNumberOfCalls(10)
          .slidingWindowType(SlidingWindowType.TIME_BASED)
          .slidingWindowSize(5)
          .recordException(e -> INTERNAL_SERVER_ERROR
                         .equals(getResponse().getStatus()))
          .recordExceptions(IOException.class, TimeoutException.class)
          .ignoreExceptions(BusinessException.class, OtherBusinessException.class)
          .build();
}   

once you have the config then create a CircuitBreakerRegistry bean with a custom global configuration

@Bean
public CircuitBreakerRegistry cbRegistry(){
      return CircuitBreakerRegistry.of(defaultConfig());
}

Now you can get or create a CircuitBreaker with the global configuration with your URL as name using the above created CircuitBreaker Registry

@Autowired
private CircuitBreakerRegistry circuitBreakerRegistry;

public boolean connect(url){
    CircuitBreaker cb = circuitBreakerRegistry.circuitBreaker(url);
    // use this cb to decorate your connection creation code.
    Decorators.ofSupplier(() -> {
        // code to make rest call
        return "";
    }).withCircuitBreaker(some).decorate().get();
}