Resilience4j - Request timeout
Asked Answered
S

1

8

I have a service which is using Hystrix circuit breaker pattern and it calls 3rd party service. With the help of

@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000")

I have defined the timeout for the 3rd party service.

Since the Hystrix is in maintenance mode, I am migrating from Hystrix to Resilience4j circuit breaker pattern. How can I achieve similar timeout handling in resiience4j.

I got to know that similar thing can be achieved by using @TimeLimiter annotation which is a part of resilience4j-timeLimiter library. But as per this issue, I have to modify the return type of my method to CompletableFuture. It will involve lot of code changes to my existing service.

How can I achieve this with Resilience4j?

Shirlshirlee answered 17/4, 2020 at 16:18 Comment(2)
Take a look at this - vinsguru.com/…Wightman
I checked the sample code over there. It is setting timeout in RestTemplate using RestTemplateBuilder. I am looking for the properties through resilience4j. Is it possible to do that?Shirlshirlee
A
6

I had to deal with the same problem as you.

For me, TimeLimiter from resilience4j solve my problem and not need to use Hystrix anymore.

This is my application.properties:

resilience4j.timelimiter.configs.default.timeout-duration=3s
resilience4j.timelimiter.instances.paymentCalc.base-config=default
# The max amount of time a call can last
resilience4j.timelimiter.instances.paymentCalc.timeout-duration=1s
# Cancel the Running Completable Futures After TimeOut.
resilience4j.timelimiter.instances.paymentCalc.cancel-running-future=true

# Max amount of parallel executions allowed by the bulkhead
resilience4j.bulkhead.configs.default.max-concurrent-calls=2
# Max amount of time a thread should be blocked for when attempting to enter a saturated bulkhead.
resilience4j.bulkhead.configs.default.max-wait-duration=0
resilience4j.bulkhead.instances.paymentCalc.base-config=default

This is my implementation:

    // Bulkhead module is added because TimeLimiter needs separate execution thread instead of request thread
    @Bulkhead(name = "paymentCalc", fallbackMethod = "localPaymentGenerate", type = Bulkhead.Type.THREADPOOL)
    @TimeLimiter(name = "paymentCalc", fallbackMethod = "localPaymentGenerate")
    @GetMapping(value = "/{workerId}/days/{days}")
    public CompletableFuture<ResponseEntity<Payment>> getPayment(@PathVariable Long workerId, @PathVariable Integer days){
            
        ...     
    }
    
    
    public CompletableFuture<ResponseEntity<Payment>> localPaymentGenerate(Long workerId, Integer days, Exception e){
        
        System.out.println(e.getMessage()); // prints "TimeLimiter 'paymentCalc' recorded a timeout exception"
    
        ...
}

But, be careful, code not worked using spring-cloud-starter-circuitbreaker-resilience4j dependencie, and i have spent a lot time trying to solve it. The only thing that i needed to change to make @TimeLimiter get works is to change my dependecies.

I'm using spring-boot <version>2.5.4</version>, <java.version>16</java.version> and my dependencies are:

 <dependency>
        <groupId>io.github.resilience4j</groupId>
        <artifactId>resilience4j-spring-boot2</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
Aeniah answered 10/9, 2021 at 18:25 Comment(6)
Looks great. I need to try your suggestions. Any idea whether does this work on Java 11? Right now, I can only work on Java versions up to 11. I may give it a try though.Shirlshirlee
Hi, i've just changed my microservice project to Java version 11 and the service continue working as expected, i think that it will be work for you too. Try to make changes above to use TimeLimiter and let i know if it works.Shareeshareholder
Awesome! Thanks for confirming. I will give it a try.Shirlshirlee
I got an error . method only supposed 'CompletableFuture-return-type' ?Gasser
Thanks a lot. "But, be careful, code not worked using spring-cloud-starter-circuitbreaker-resilience4j dependencie, and i have spent a lot time trying to solve it. The only thing that i needed to change to make @TimeLimiter get works is to change my dependecies." should be in Bold. This was exactly the issue.Gulfweed
I used your code on a sevice layer and the cancel-running-future is not cancelling the execution of the. CompletableFutureSympathy

© 2022 - 2024 — McMap. All rights reserved.