Java – Automatic retry with Ribbon (no zuul): not working + wrong documentation?

Automatic retry with Ribbon (no zuul): not working + wrong documentation?… here is a solution to the problem.

Automatic retry with Ribbon (no zuul): not working + wrong documentation?

In the latest version of the official Spring Cloud Netflix documentation (e.g. 2.0.2. RELEASE, the last GA version).

When Spring Retry is present, load-balanced RestTemplates, Feign, and Zuul automatically retry any failed requests (assuming your configuration allows doing so).

But the use of independent ribbons (that is, load-balanced RestTemplates) seems wrong. I can’t get it to work and I can’t find any working examples. In addition, I found that other sources say the opposite, such as:

So, is it a documentation error or is the whole world missing something?

Solution

We found the same issue; Zuul neither retries nor fails over to an alternate server in the list of ribbon servers using the default (Apache Http client) configuration. We tracked down to this line of code in the RibbonLoadBalancingHttpClient class:

@Override
public RequestSpecificRetryHandler getRequestSpecificRetryHandler(
        RibbonApacheHttpRequest request, IClientConfig requestConfig) {
    return new RequestSpecificRetryHandler(false, false, RetryHandler.DEFAULT,
            requestConfig);
}

Hard-coded false, false parameters effectively prevent retries from occurring. It’s easy to solve this problem.

Add this to your Zuul main application class:

@RibbonClients(
    defaultConfiguration = {EurekaRibbonClientConfiguration.class,
        MyRibbonConfiguration.class})

Create a class MyRibbonConfiguration and use it to emulate the ribbonLoadBalancingHttpClient method here except that we overridden and fixed the getRequestSpecificRetryHandler method that caused the problem.

public class MyRibbonConfiguration {

@RibbonClientName
  private String name = "client";

@Bean
  public RibbonLoadBalancingHttpClient ribbonLoadBalancingHttpClient(
      IClientConfig config, ServerIntrospector serverIntrospector,
      ILoadBalancer loadBalancer, RetryHandler retryHandler, CloseableHttpClient httpClient) {

RibbonLoadBalancingHttpClient client =
        new RibbonLoadBalancingHttpClient(httpClient, config, serverIntrospector) {
          @Override
          public RequestSpecificRetryHandler getRequestSpecificRetryHandler(
              RibbonApacheHttpRequest request, IClientConfig requestConfig) {
            return new RequestSpecificRetryHandler(true, true, RetryHandler.DEFAULT,
                requestConfig);
          }
        };

client.setLoadBalancer(loadBalancer);
    client.setRetryHandler(retryHandler);

Monitors.registerObject("Client_" + this.name, client);
    return client;
  }
}

If needed, adjust true, true to reference from the property. With this, Zuul will start complying with the ribbon. MaxAutoRetries and ribbon. MaxAutoRetriesNextServer property.

Note that if you use ribbon with Feign for server-> server calls, those Feign calls are not affected because OpenFeign hardcodes these two parameters to true, true.

Related Problems and Solutions