I attempted for many days now to set up a Retry mechanism using Ribbon and Feign, It is a Spring boot/ Cloud Client application consuming an external API. API randomly at times send 40X code behavior that I want my client to adapt to via resilience features,
When I retry manually about [4-5] times manually I will get 7/10 valid payload. So now for learning purpose, I want to configure this with a Retry pattern via Ribbon configuration. I am planning to write unit tests as I go,
Are there any conflict or incompatibility of Retry with Ribbon + FallBack Using Spring Boot & Cloud. See below my configuration, (pom,xml and application.properties)
Below my pom.xmlproperties
pom.xml
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- enables wiremock server for and server stub testing -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-contract-stub-runner</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-standalone</artifactId>
<version>2.19.0</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
Below my application properties
Name of the "Client Load Balance" ribbon client
spring.application.name=resilientfeign
The Feign client supports the circuit-breaker pattern by using Hystrix
feign.hystrix.enabled=true server.port = 8080
TODO the circuit-breaker pattern by using Hystrix, ribbon.ReadTimeout should be lower than the value of Hystrix's execution.isolation.thread.timeoutInMilliseconds
resilientfeign.ribbon.eureka.enabled: true resilientfeign.ribbon.MaxAutoRetries: 1 resilientfeign.ribbon.MaxAutoRetriesNextServer: 2 resilientfeign.ribbon.ConnectTimeout: 500 resilientfeign.ribbon.ReadTimeout: 1000
Comment From: ryanjbaxter
I dont believe Ribbon retries on 40x response codes by default
You can configure which status codes you want to retry using clientName.ribbon.retryableStatusCodes.
http://cloud.spring.io/spring-cloud-static/Greenwich.SR1/single/spring-cloud.html#_configuration
Please learn how to format code on GitHub.
Comment From: spring-projects-issues
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.
Comment From: giventech
Hi Ryan, I have tried many times with this configuration below ( I think I probably have tried this before The client still does not Retry after error code 400 is returned. I was wondering. I am looking at other possible cause perhaps conflicts with my fallbackFactory
resilientfeign.ribbon.eureka.enabled: true resilientfeign.ribbon.MaxAutoRetries: 4 resilientfeign.ribbon.MaxAutoRetriesNextServer: 2 resilientfeign.ribbon.ConnectTimeout: 500 resilientfeign.ribbon.ReadTimeout: 1000 resilientfeign.ribbon.retryableStatusCodes: 400, 404
My fallback factory :
@Component
public class ResilientClientFallbackFactory implements FallbackFactory<ResilientClient > {
@Override
public ResilientClient create(Throwable cause) {
return new ResilientClient () {
@Override
public Set<CarShow> getCarShows() {
if (cause instanceof FeignException && ((FeignException) cause).status() >= 400) {
//TODO Add a trace for monitoring
}
Set <CarShow> carShowSet = new HashSet<CarShow>();
CarShow carShow = new CarShow("Downstream service unavailable",new ArrayList<Car>());
carShowSet.add(carShow);
return carShowSet;
}
};
}
}
Comment From: ryanjbaxter
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.
Comment From: spring-projects-issues
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.
Comment From: spring-projects-issues
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.
Comment From: giventech
Hello I haven’t had time to provide you with the code can you allow a few more days. Kind regards
Comment From: spencergibb
No worries, when you do, we'll reopen.
Comment From: git-syl
Hello, I have the same problem. And finally I found that if you @Configuration LoadBalancedRetryFactory BackOffPolicy , the ribbon.MaxAutoRetries will not working. @ryanjbaxter @spencergibb https://docs.spring.io/spring-cloud-netflix/docs/2.2.10.RELEASE/reference/html/#retrying-failed-requests
I upload a complete, minimal, verifiable sample that reproduces the problem.
https://github.com/sunyl-git/feign-spring-retry-test-issue
Reproduces Step : (Run applicaitons, and curl http://localhost:8080/callFeign Observe the print result in TestController.java , then delete BackOffPolicyConfiguration.java curl http://localhost:8080/callFeign )