spring-cloud-circuitbreaker icon indicating copy to clipboard operation
spring-cloud-circuitbreaker copied to clipboard

Resilience4j's TimeLimiter triggered after feign response in postConstruct() callback

Open DevDengChao opened this issue 4 years ago • 18 comments

Describe the bug Like the title said. I found that Resilience4j's TimeLimiter always triggered even feign client received response when feign method's return type is not void.

I'm using: OpenJDK 1.8.0_292-b10 and 11.0.11.9-hotspot Spring boot 2.5.2 Spring cloud 2020.0.3

Sample Here: https://github.com/DevDengChao/resilience4j-time-limiter-triggered-after-feign-response

DevDengChao avatar Jul 28 '21 15:07 DevDengChao

This is either some race condition with @PostConstruct or an issue with the bean proxies on the Application class. If you move the code to a controller class, it works fine.

eduardolbueno avatar Jan 07 '22 15:01 eduardolbueno

@eduardolbueno Thanks, I've updated the sample project and split it into two show case.

  1. Perform Feign request in any component's postConstruct() callback will reproduce this issue. See FeignClientsWarmup class and its test case in the sample project.
  2. Perform Feign request in any controller's request handlers will not reproduce this issue. See RootController class and its test case in the sample project.

Maybe I can perform a one-time async task right after the application started to warm up my Feign clients instead of using the postConstruct() callback.

DevDengChao avatar Jan 08 '22 08:01 DevDengChao

If it is a functional requirement of your application then you could try other startup mechanisms, e.g.

https://www.baeldung.com/running-setup-logic-on-startup-in-spring

eduardolbueno avatar Jan 08 '22 20:01 eduardolbueno

@DevDengChao does this only happen when using OpenFeign?

ryanjbaxter avatar Feb 07 '22 00:02 ryanjbaxter

@DevDengChao does this only happen when using OpenFeign?

Emm, I'm not certain, as I don't know what to test next. 🤣 Do you mean RestTemplate ?

DevDengChao avatar Feb 08 '22 00:02 DevDengChao

Yes you could make a call using RestTemplate and wrap it in a CircuitBreaker.

ryanjbaxter avatar Feb 08 '22 00:02 ryanjbaxter

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

spring-cloud-issues avatar Feb 21 '22 21:02 spring-cloud-issues

@ryanjbaxter I'd like to provide you such test cases, but I'm not familiar with RestTemplate and I'm little busy these weeks.

Maybe I'll give it one more try this week.

DevDengChao avatar Feb 22 '22 01:02 DevDengChao

Sounds good, thanks!

ryanjbaxter avatar Feb 22 '22 01:02 ryanjbaxter

I also find this problem. it will make a feign call during initialization.

  • reson:
    • the thread is waiting Main thread release locak (singletonObjects) when calling http request.
  • I'm using
    • spring boot 2.7.1
    • spring cloud 2021.0.3 using open feign
    • oracle open jdk version 18.0.1

gamelike avatar Aug 17 '22 08:08 gamelike

@gamelike Can you provide a complete, minimal, verifiable sample that reproduces the problem? It should be available as a GitHub (or similar) project or attached to this issue as a zip file.

ryanjbaxter avatar Aug 17 '22 18:08 ryanjbaxter

@ryanjbaxter The demo link : https://github.com/gamelike/spring-circuit-breaker-sample-demo It just show circuit-breaker time out exception. And I put thread-dump.txt in project.

gamelike avatar Aug 18 '22 03:08 gamelike

@ryanjbaxter Hi, I finally have some time updating the sample repository, there is a RestTemplateWarmup class now.

I followed https://spring.io/projects/spring-cloud-circuitbreaker#core-concepts this guide to wrap a rest template inside resilience4j.

You can try running the sample app to see rest template works fine with resilience4j but feign clients not.

DevDengChao avatar Aug 18 '22 03:08 DevDengChao

@gamelike @DevDengChao thanks for the samples.

It looks like we are experiencing a bit of a deadlock due to the feign client calls happening curing bean creation.

The feign client calls are blocking waiting for a response.

The circuit breakers are run in a separate thread. The request is made to the remote service, but then Feign is trying to decode the response. This is calling this line https://github.com/spring-cloud/spring-cloud-openfeign/blob/3.1.x/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/support/SpringDecoder.java#L70

This ends up trying to access a ConcurentHashMap which is currently locked by the bean post processor.

If you use Spring Cloud 2021.0.4-SNAPSHOT and set the property spring.cloud.circuitbreaker.resilience4j.disableThreadPool=true I think things should work. Could you give that a try?

ryanjbaxter avatar Aug 18 '22 21:08 ryanjbaxter

@ryanjbaxter thanks for your reply.

If you use Spring Cloud 2021.0.4-SNAPSHOT and set the property spring.cloud.circuitbreaker.resilience4j.disableThreadPool=true I think things should work. Could you give that a try?

~~How i should build 2021.0.4-SNAPSHOT, I'll try.~~ yes, it works.

In prod env, I can't update version to 2021.0.4-SNAPSHOT, is there any other way to solve this problem?

gamelike avatar Aug 19 '22 02:08 gamelike

If you use Spring Cloud 2021.0.4-SNAPSHOT and set the property spring.cloud.circuitbreaker.resilience4j.disableThreadPool=true I think things should work. Could you give that a try?

@ryanjbaxter It works. thanks.

DevDengChao avatar Aug 19 '22 02:08 DevDengChao

Thanks @gamelike and @DevDengChao.

If this solution works then we will just have to wait for our next release to take advantage of it. Our next release is planned for the end of this month

ryanjbaxter avatar Aug 19 '22 12:08 ryanjbaxter

Thanks @ryanjbaxter for the answer.

gamelike avatar Aug 19 '22 13:08 gamelike