resilience4j / resilience4j-spring-boot2-demo

A Spring Boot 2 demo which shows how to use the Resilience4j Spring Boot 2 Starter
Apache License 2.0
254 stars 190 forks source link

CircuitBreaker with Retry #29

Closed MMaalej closed 4 years ago

MMaalej commented 4 years ago

Hi,

I want to define a Cuircuit-Breaker with retry for a restcall. My Config:

resilience4j.circuitbreaker:
    configs:
        default:
            registerHealthIndicator: false
            slidingWindowSize: 10
            minimumNumberOfCalls: 2
            permittedNumberOfCallsInHalfOpenState: 3
            automaticTransitionFromOpenToHalfOpenEnabled: true
            waitDurationInOpenState: 10s
            slowCallDurationThreshold: 10
            slowCallRateThreshold: 30
    instances:
        restCallCB:
            baseConfig: default

resilience4j.retry:
    configs:
        default:
            maxRetryAttempts: 2
            waitDuration: 1000
    instances:
        restCallRE:
            baseConfig: default

I use this spring annotation:

@CircuitBreaker(name = "restCallCB")
@Retry(name = "restCallRE", fallbackMethod = "fallbackRetry")
public String callRest(...)

I use a wrong URL to test the restcall. Problem: the retry will not be executed und the circuit breaker ist alway closed.

If I define a fallback-Method for the circuit breaker, the first test call this fallback-Method and the retry will not be executed. Without the circuit breaker the retry works fine.

Could you please help me find the right config.

Thanks, Maalej

RobWin commented 4 years ago

Which version of Resilience4j are you using? Which exception is thrown in your test?

The class with the callRest method is a @Component bean?

MMaalej commented 4 years ago

Hi,

io.github.resilience4j resilience4j-spring-boot2 1.2.0

Exception: [Request processing failed; nested exception is org.springframework.web.client.HttpClientErrorException$NotFound: 404 null]

Yes, the Class is @Component bean that will be created with the AutoConfig.

Thanks

RobWin commented 4 years ago

Please update to 1.3.1. It should work then.

MMaalej commented 4 years ago

Thanks, It works now, but without fallbackMethod for the circuit breaker. @CircuitBreaker(name = "restCallCB") @Retry(name = "restCallRE", fallbackMethod = "fallbackRetry")

when the Circuitbreaker fallback will be called? maybe i dont need this fallback.

RobWin commented 4 years ago

The fallback method of the CircuitBreaker handles exceptions before they are propagated to the Retry decorator.

MMaalej commented 4 years ago

What should I do, if I want to call a Method after the retrys are executed and the circuitbreaker is open?

After the retrys are excuted the fallback of retry will be called. If the Circuitbreaker is open, the fallback of the Circuitbreaker will be called?

RobWin commented 4 years ago

Define a fallback as follows. The fallback is only invoked when the CircuitBreaker is open.

private String fallback(CallNotPermittedException ex) {
        ...
    }
@CircuitBreaker(name = "restCallCB", fallbackMethod = "fallback")
@Retry(name = "restCallRE", fallbackMethod = "fallbackRetry")
MMaalej commented 4 years ago

Thanks, recapitulation: CircuitBreaker is closed: the retrys will be executed and the fallback of the retrys will be invoked. CircuitBreaker is open: the fallback of the Circuitbreaker will be invoked without Retrys.

?

Thank you very much.

RobWin commented 4 years ago

Yes

RobWin commented 4 years ago

Alternative. Don't have a CircuitBreaker fallback, but instead add the CallNotPermittedException to the list of ignored exceptions in your Retry configuration.

MMaalej commented 4 years ago

If i add the CallNotPermittedException to the list of ignored exceptions in my Retry configuration, which method will be invoked, if the CircuitBreaker is open.

Config:
resilience4j.retry: configs: default: maxRetryAttempts: 2 waitDuration: 1000 ignoreExceptions: io.github.resilience4j.circuitbreaker.CallNotPermittedException instances: restCallRE: baseConfig: default

public String fallbackRetry(....., HttpClientErrorException e) {

RobWin commented 4 years ago

You can add a second fallback method with the same name but different signature.

public String fallbackRetry(....., CallNotPermittedException e) {
RobWin commented 4 years ago

If it works for you, please close the issue

MMaalej commented 4 years ago

ok, the first solution works fine :-)

Thanks