多个Feign客户端超时配置

huangapple go评论71阅读模式
英文:

Multiple Feign client timeout configurations

问题

如果您更喜欢使用配置属性来配置所有的 @FeignClient,您可以创建带有默认 feign 名称的配置属性。还可以通过为客户端命名来针对特定客户端设置这些超时时间。当然,我们还可以毫无问题地同时列出全局设置和每个客户端的覆盖设置。

我的客户端:

@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-client 是 5000,而不适用于其他客户端。但它似乎忽略了 foo-client 的配置,而只使用默认配置。

我知道这不是 @Configuration 类的问题,因为 Feign 文档指出,如果我们既创建了 @Configuration Bean 又创建了配置属性,配置属性将覆盖。
英文:

> If you prefer using configuration properties to configured all @FeignClient, you can create configuration properties with default feign name. It's also possible to set these timeouts per specific client by naming the client. And, we could, of course, list a global setting and also per-client overrides together without a problem.

My client:

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

I'm trying to do this and I want foo-client.readTimeout to override default.readTimeout when I'm using foo-client:

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"

But this is not happening. I'm not sure if Hystrix's timeoutInMilliseconds could be impacting, but from my tests, it's not interfering. I want the feign.readTimeout to be 5000 only for the foo-client, not for the other clients. But it looks like it is ignoring this foo-client configuration and using only the default configuration.

I know it's not a @Configuration class problem because the Feign documentation says that if we create both @Configuration bean and configuration properties, configuration properties will win.

答案1

得分: 2

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

我建议您使用配置类来处理多个带有hystrix的feign客户端,而不是编辑您的application.yml文件。以下示例设置了一个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);
    }
}
英文:

As you have seen in the documentation, you can set timeouts per specific client. But you have only configured it for feign client, not for hystrix command. Remember that they have independent timeouts.

I would recommend to use a configuration class instead of editing your application.yml in order to handle multiples feign clients with hystrix. The following example sets up a Feign.Builder where timeouts are being injected for Feign client and Hystrix command.

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

huangapple
  • 本文由 发表于 2020年7月27日 21:38:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/63116582.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定