CircuitBreaker: How to treat exceptions as a success
See original GitHub issueHi,
I have the following setup:
- A 3rd party service (runs on localhost:8090/sample) and it always returns bad request (400).
@RestController
@RequestMapping
public class SampleController {
@GetMapping("/sample")
public ResponseEntity helloWorld(HttpServletResponse response) {
System.out.println("Request received");
return ResponseEntity.badRequest().body("{\"message\":\"this is a bad request\"}");
}
}
- In my main application where I am using circuit breaker, I am using RestTemplate to communicate it with the 3rd party service. I have ignored
org.springframework.web.client.HttpClientErrorException
from the circuit breaker. - The circuit breaker annotation is kept at method level like below:
@CircuitBreaker(name = "callOtherService", fallbackMethod = "errorExternal")
public String callOtherService() {
System.out.println("Call received");
return restTemplate.getForObject(URI.create("http://localhost:8090/sample"), String.class);
}
public String errorExternal(Throwable throwable) {
return "This is error from fallback triggered by external error";
}
- I am using following configuration (see
callOtherService
section)
resilience4j.circuitbreaker:
configs:
default:
registerHealthIndicator: true
ringBufferSizeInClosedState: 4
ringBufferSizeInHalfOpenState: 2
automaticTransitionFromOpenToHalfOpenEnabled: true
waitDurationInOpenState: 20s
failureRateThreshold: 50
eventConsumerBufferSize: 10
ignoreExceptions:
- com.resilience4j.exception.BusinessException
- feign.FeignException
recordExceptions:
- java.net.SocketTimeoutException
- java.net.ConnectException
shared:
registerHealthIndicator: true
ringBufferSizeInClosedState: 4
ringBufferSizeInHalfOpenState: 2
waitDurationInOpenState: 20s
failureRateThreshold: 50
eventConsumerBufferSize: 10
ignoreExceptions:
- com.resilience4j.exception.BusinessException
instances:
callOtherService:
baseConfig: default
ringBufferSizeInClosedState: 4
registerHealthIndicator: true
ignoreExceptions:
# We need to ignore 4xx errors returned by the server as they are valid business case.
- org.springframework.web.client.HttpClientErrorException
recordExceptions:
# We need to record all http errors
- org.springframework.web.client.RestClientException
Steps to reproduce:
- Call the exposed endpoint 5-6 times. Verify the 3rd party service gets the call every time.
- Shut down the 3rd party service.
- Call the exposed endpoint again for 4 times. Check /actuator/health endpoint and you’ll see that the circuit is OPEN now.
- Wait for 20 sec.
- Now health endpoint says circuit is HALF_OPEN.
- Call exposed endpoint again for 2 times.
- Check health endpoint and verify circuit is OPEN again.
- Turn ON the 3rd party service.
- Verify from health endpoint if circuit is HALF_OPEN.
- Call the exposed endpoint. The call gets successful to 3rd party 2 times (size of ring buffer in half open state).
- Health endpoint still HALF_OPEN.
- All the calls to exposed endpoint are short-circuited and no call is attempted to the 3rd party.
- The circuit breaker is never CLOSED again. And there is no way to recover from this situation apart from restart the server using the circuit breaker.
Issue Analytics
- State:
- Created 4 years ago
- Comments:31 (24 by maintainers)
Top Results From Across the Web
How to Prevent Certain Exceptions from Tripping a ...
You can either ignore the exceptions you want to no longer count, or you can be explicit about the kinds of exceptions you...
Read more >Failover and Circuit Breaker with Resilience4j | by Rob Golder
Here we see there are two overloaded fallback methods. In fact any number can be provided, with the last argument, the exception type,...
Read more >Implementing a Circuit Breaker with Resilience4j - Reflectoring
A deep dive into the Resilience4j circuit breaker module. This article shows why, when and how to use it to build resilient applications....
Read more >Examples - resilience4j
If you want to recover from an exception after the CircuitBreaker recorded it as a failure, you can chain the method Vavr´s. Try.recover()...
Read more >Resilience4J Circuit Breaker to kick-in on specific HTTP status ...
By default the circuit-breaker reacts on exceptions. It records them and will open the circuit if there are too much in too less...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
But I like the idea to add something like
But it is not necessary for an endpoint to return 200 to show that it is running properly. If any endpoint is returning 400 (valid case if the request fails validation error) that means also that the endpoint is working, right? As per me all the 4xx errors should be treated as successful call and only 5xx should be considered as failure because the 5xx ones are the ones which are related to server health.