Spring-cloud-netflix: Feign Retryer is not configurable and overlaps with the ribbon retry.

Created on 29 Jul 2015  路  7Comments  路  Source: spring-cloud/spring-cloud-netflix

I have a consumer service calling an provider service which is running with 2 instances.
The provider interface

  @FeignClient("example")
  public interface ExampleService {
     @RequestMapping(
        method = {RequestMethod.POST},
        value = {"/greeting/{nameToGreat}"}
      )
     String greeting(@PathVariable(value = "nameToGreat") String nameToGreat);

The ribbon configuration within the consumer service is as follows:

example.ribbon.OkToRetryOnAllOperations=false
example.ribbon.ReadTimeout=3999
example.ribbon.MaxAutoRetries=0
example.ribbon.MaxAutoRetriesNextServer=3

If there is a SocketTimeoutException during a call to the example service, I would not expect that there a retry to the next instance occurs, because POST requests are not idempotent.
But the real behavior is that there retries to the next instance occurs which causes creation of duplicate accounts aso.

In a debugging session I could see that a correct RequestSpecificRetryHandler with the ribbon config values from above will be created and as far I could see the method isRetriableException(...) of that handler returns false.

What can I do to find a solution?
Thanx
Lutz

enhancement help wanted

Most helpful comment

We've eliminated the feign retry with our ribbon retry

All 7 comments

Now I found that the FeignClient uses the default retryer which retries the failed requests on its own.
I think this is not desired, because it overrules the configuration for the ribbon loadbalancer.
Maybe this is not a feature, is it?
Lutz

Perhaps the default should be an empty Retryer.

As a workaround, you can create a Retryer bean in a Feign Client Configuration.

Workaround works like a charm:

  @Bean
  public Retryer retryer() {
    return new Retryer() {

      @Override
      public void continueOrPropagate(RetryableException e) {
        throw e;
      }

      @Override
      public Retryer clone() {
        return this;
      }
    };
  }

There's a NEVER_RETRY implementation so you can do

@Bean public Retryer retryer() { return Retryer.NEVER_RETRY; }

We can close this issue because all this retry logic was simplified in the latest Camden SRs and and Dalston snapshots and there is only one level of retry now.

Can you explain what you mean by 'there is only one level of retry now'?

We've eliminated the feign retry with our ribbon retry

Was this page helpful?
0 / 5 - 0 ratings