我成功地使用Eureka让我的RestTemplate客户端发现远程服务,并使用Ribbon将调用转发给它,如文档中所述。 基本上,只需添加我的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代理和假装客户这样做"开箱即用"所以我相信图书馆拥有必要的功能......
任何想法/提示?
THX, /勃氏
答案 0 :(得分: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
}
在这种形式下,即使重试成功,每次失败都会计入断路器指标(也许我们可能会改变这种情况,或者可能会这样做),即使重试成功也是如此。
答案 1 :(得分:0)
由于拦截器的顺序,无论@Configuration类或@Retryable方法上的注释顺序如何,我都无法使用@HystrixCommand和@Retryable。我通过使用匹配的方法集创建另一个类并将@HystrixCommand带注释的方法委托给第二个类中相应的@Retryable方法来解决这个问题。你可能有两个类实现相同的接口。这对屁股来说是一种痛苦,但是直到订单可以配置,这就是我能想到的。仍在等待Dave Syer和春云人的真正解决方案。
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;
}
}