有一个服务A,主要依赖如下:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
springcloud的版本是Edgware.SR4,springboot的版本是1.5.8.RELEASE
配置文件:
feign.hystrix.enabled: true
一个feign客户端:
@FeignClient(name = "aaa-service", fallback = SOperatorClientFallBack.class)
public interface SOperatorClient {
@RequestMapping("/operator/getName")
Map<String, String> getUserNamesByIds(@RequestParam("ids") List<String> ids);
}
测试这个SOperatorClient#getUserNamesByIds方法的时候发现一直调用服务降级逻辑,甚至都感觉不到它试图调用aaa-service,然后调用失败再报错,而是直接就调用降级逻辑,之后查阅资料,又在配置文件中添加了如下配置:
feign.hystrix.enabled: true
ribbon:
ReadTimeout: 10000
ConnectTimeout: 5000
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 20000
调用成功,不禁感慨在feign中ribbon和hystrix的默认配置真的是垃圾。但是话说回来,其实ribbon和hystrix的配置其实也是一门艺术,因为一个是远程调用,一个是服务熔断,一旦而是在某些时间上配置的不够合理,其实就和没配置一样,比如说服务熔断配置的时间小于远程调用的时间,想象一下,远程调用还没结束呢,熔断器就说时间到了调用失败了,是不是很荒唐?
紧接着,我又把aaa-service停掉,想测试一下服务降级,但是结果却令人感到失望,还是感觉服务没有任何调用就直接降级,刷的一下就过去了,难道配置的ribbon的连接时间和ReadTimeout都是闹着玩的吗?调整日志级别为debug,又试了一次,才发现其实不是我认为的那样,因为有这样一条报错:
java.lang.RuntimeException: com.netflix.client.ClientException: Load balancer does not have available server for client: aaa-service
也就是说其实它是调用了aaa-service的,只不过找不到这个服务而已。但是为什么没有重试呢?万一此时是因为网络抖动而没找到aaa-service呢,就这样宣布调用失败吗?经过查阅资料,在配置文件中加入如下配置:
feign.hystrix.enabled: true
ribbon:
ReadTimeout: 10000
ConnectTimeout: 5000
MaxAutoRetriesNextServer: 3
ribbon.MaxAutoRetries: 3
OkToRetryOnAllOperations: true
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 20000
经过测试发现调用失败后又重试了一次,可以我明明设置的是重试3次啊,难道这个参数没起作用,另外,为什么这个yml文件在我配置上述的这些参数均没有给我提示呢?这里留一个疑问,以后有时间了就过来解决。