使用 Ribbon 自动重试(没有 zuul):不工作+错误的文档?

Automatic retries with Ribbon (without zuul): not working + wrong documentation?

在最新版本的 spring cloud Netflix 的官方文档(例如 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).

但是关于独立功能区(即负载平衡的 RestTemplates)的使用似乎是错误的。我无法让它工作,也找不到任何工作示例。此外,我发现其他来源的说法恰恰相反,例如:

那么,是文档有误还是整个世界都遗漏了什么?

我们发现了同样的问题; Zuul 既不会使用默认(Apache Http 客户端)配置重试也不会故障转移到功能区服务器列表中的备用服务器。我们在 RibbonLoadBalancingHttpClient class:

中追踪到了 this line of code
@Override
public RequestSpecificRetryHandler getRequestSpecificRetryHandler(
        RibbonApacheHttpRequest request, IClientConfig requestConfig) {
    return new RequestSpecificRetryHandler(false, false, RetryHandler.DEFAULT,
            requestConfig);
}

硬编码的 false, false 参数有效地禁止重试发生。很容易解决这个问题。

将此添加到您的 Zuul 主应用程序 class:

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

创建一个 class、MyRibbonConfiguration 并使用它来模拟 ribbonLoadBalancingHttpClient 方法 here 除了我们覆盖并修复导致问题的 getRequestSpecificRetryHandler 方法.

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;
  }
}

如果需要,请调整 true, true 以从属性中引用。有了这个,Zuul 将开始遵守 ribbon.MaxAutoRetriesribbon.MaxAutoRetriesNextServer 属性。

请注意,如果您将 Ribbon 与 Feign 一起用于服务器-> 服务器调用,那么这些 Feign 调用不会受到影响,因为 OpenFeign 将这两个参数硬编码为 true, true.