In the latest versions of spring cloud Netflix's official documentation (for example 2.0.2.RELEASE, the last GA version) it states:
When Spring Retry is present, load-balanced RestTemplates, Feign, and Zuul automatically retry any failed requests (assuming your configuration allows doing so).
But that seems wrong concerning the use of standalone Ribbon (i.e. load-balanced RestTemplates). I couldn't make it work nor found any working example. Moreover, I found other sources stating quite the opposite was true, such as:
So, it's the documentation wrong or is the whole world missing something?
We found the same issue; Zuul will neither retry nor failover to alternative servers in the ribbon server list using the default (Apache Http Client) configuration. We tracked it 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);
}
The hardcoded false, false
parameters effectively disable retry from ever happening. It is easy to fix this.
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 we override and fix the getRequestSpecificRetryHandler
method that's causing problems.
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;
}
}
Adjust true, true
to reference from properties if you want. With this in place Zuul will start respecting the ribbon.MaxAutoRetries
and ribbon.MaxAutoRetriesNextServer
properties.
Note that if you are using Ribbon with Feign for server->server calls then those Feign calls are not affected because OpenFeign hardcodes those two parameters to true, true
.