多个Feign客户端超时配置

时间:2020-07-27 13:38:38

标签: java client hystrix spring-cloud-feign feign

如果您希望使用配置属性来配置所有@FeignClient,则可以使用默认伪名称创建配置属性。也可以通过命名客户端为每个特定的客户端设置这些超时。 而且,我们当然可以列出全局设置,并且每个客户端也可以一起覆盖,而不会出现问题

我的客户:

@FeignClient( contextId = "fooFeignClient", name = "foo-client", url = "${foo.url}",
    fallbackFactory = FooFallBackFactory.class,
    configuration = FooFeignConfiguration.class)

我正在尝试执行此操作,并且我希望在使用foo-client时foo-client.readTimeout覆盖default.readTimeout:

feign:
  hystrix:
    enabled: true
  client:
    config:
      default:
        connectTimeout: 3000
        readTimeout: 3000
        loggerLevel: full
      foo-client:
        connectTimeout: 3000
        readTimeout: 5000        
hystrix:
  command:
    default:
      execution:
        timeout:
          enabled: "false"
        isolation:
          strategy: "THREAD"
          thread:
            timeoutInMilliseconds: "3000"

但是这没有发生。我不确定Hystrix的timeoutInMilliseconds是否会产生影响,但是从我的测试来看,它不会造成干扰。我希望feign.readTimeout仅对于foo客户端为5000,而不对于其他客户端。但是看起来它正在忽略此foo-client配置,而仅使用默认配置。

我知道这不是@Configuration类问题,因为Feign文档指出,如果我们同时创建@Configuration bean和配置属性,则配置属性将获胜。

1 个答案:

答案 0 :(得分:1)

正如您在文档中所看到的,您可以为每个特定的客户端设置超时。但是,您只为假客户端配置了它,而不为hystrix命令配置了它。请记住,它们具有独立的超时时间。

我建议使用配置类,而不是编辑application.yml,以便使用hystrix处理多个假客户端。以下示例设置了一个Feign.Builder,其中将为Feign客户端和Hystrix命令注入超时。

# application.yml
microservices:
    foo:
        feign:
            url: xxxx
            connect-timeout: 5s
            read-timeout: 5s
        hystrix:
            enabled: true
            timeout: 5s
@FeignClient(name = "foo",
             url = "${microservice.foo.feign.url}",
             configuration = FooFeignConfiguration.class)
public interface FooFeignRepository {
}
@Configuration
@RequiredArgsConstructor
public class FooFeignConfiguration {
    
    @Value("${microservice.foo.hystrix.enabled:true}")
    private final Boolean hystrixEnabled;

    @DurationUnit(value = ChronoUnit.MILLIS)
    @Value("${microservice.foo.feign.connect-timeout:5000}")
    private final Duration feignConnectTimeout;
    
    @DurationUnit(value = ChronoUnit.MILLIS)
    @Value("${microservice.foo.feign.read-timeout:5000}")
    private final Duration feignReadTimeout;
    
    @DurationUnit(value = ChronoUnit.MILLIS)
    @Value("${microservice.foo.hystrix.timeout:5000}")
    private final Duration hystrixTimeout;

    @Bean
    @Scope("prototype")
    public Feign.Builder feignBuilder() {
        return (hystrixEnabled ?
            HystrixFeign.builder()
                .options(new Request.Options(
                    (int) feignConnectTimeout.toMillis(), 
                    (int) feignReadTimeout.toMillis()))
                .setterFactory((target, method) -> {
                    return new SetterFactory.Default()
                        .create(target, method)
                        .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                            .withExecutionTimeoutInMilliseconds((int) hystrixTimeout.toMillis()));
                }):
            Feign.builder())
        .retryer(Retryer.NEVER_RETRY);
    }
}