3

我成功地让我的 RestTemplate 客户端使用 Eureka 发现远程服务,并使用功能区将调用转发给它,如文档中所述。基本上,只需在我的 Application 类中添加以下注释,然后让 Spring-Boot 的魔力完成剩下的工作:

@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableDiscoveryClient

(PS:您注意到我使用的是 spring-cloud:1.0.0-SNAPSHOT-BUILD 而不是 1.0.0.M3 - 但这似乎不会影响我的问题)。

当两个服务实例启动时,rest-template 客户端成功地对两者之间的请求进行负载均衡。但是,如果第一个实例在 Eureka 负载均衡器通知之前停止,客户端将不会回退到第二个实例,而是引发异常。

因此我的问题是:有没有办法配置 RestTemplate/Ribbon/Eureka 堆栈,如果第一个选择的实例不可用,则自动重试对另一个实例的调用?Zuul 代理和 feign 客户端“开箱即用”执行此操作,因此我相信该库拥有必要的功能......

任何想法/提示?

谢谢,/伯特兰

4

2 回答 2

4

RestTemplate支持本身不知道如何进行任何重试(而 Spring Cloud 中的 Feign 客户端和代理支持则知道,正如您所注意到的)。我认为这可能是一件好事,因为它使您可以选择自己添加它。例如,使用Spring Retry,您可以使用简单的声明式样式进行操作:

@Retryable
public Object doSomething() {
   // use your RestTemplate here
}

(并添加@EnableRetry到您的@Configuration)。它与@HystrixCommand(来自 Spring Cloud / Javanica)完美结合:

@HystrixCommand
@Retryable
public Object doSomething() {
   // use your RestTemplate here
}

在这种形式中,即使重试成功,每次失败都计入断路器指标(也许我们可以改变它,或者保持这样的状态是有意义的)。

于 2014-12-15T06:25:28.487 回答
0

由于拦截器的顺序,无论@Configuration 类或@Retryable 方法上的注释顺序如何,我都无法让它与@HystrixCommand 和@Retryable 一起使用。我通过使用匹配的方法集创建另一个类来解决这个问题,并将 @HystrixCommand 注释的方法委托给第二个类中相应的 @Retryable 方法。您可能会让这两个类实现相同的接口。这有点让人头疼,但在可以配置订单之前,这就是我能想到的。仍在等待 Dave Syer 和 spring cloud 人员的真正解决方案。

public class HystrixWrapper {
    @Autowired
    private RetryableWrapper retryableWrapper;

    @HystrixCommand
    public Response doSomething(...) {
        return retryableWrapper.doSomething(...);
    }
}

public class RetryableWrapper {
    @Autowired
    private RestTemplate restTemplate;

    @Retryable
    public Response doSomething(...) {
        // do something with restTemplate;
    }
}
于 2015-10-12T19:18:43.210 回答