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 )