【问题标题】:Multiple Feign client timeout configurations多个 Fe​​ign 客户端超时配置
【发布时间】:2020-11-16 20:36:16
【问题描述】:

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

我的客户:

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

我正在尝试这样做,并且我希望 foo-client.readTimeout 在我使用 foo-client 时覆盖 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 和配置属性,配置属性将会获胜。

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 我这样做了,但我一直在 foo 客户端上获得 3000 毫秒的超时 :( feign.client.config.default.connectTimeout=3000 feign.client.config.default.readTimeout=3000 feign.client.config.foo-client.connectTimeout=3000 feign.client.config.foo-client.connectTimeout=3000 feign.client.config.foo-client.readTimeout=5000 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3000 hystrix.command.foo-client.execution.isolation.thread.timeoutInMilliseconds=5000
    • 您的连接超时低于读取超时。第一个属性限制打开连接所需的时间,第二个属性确定连接打开后等待应答的挂起时间。因此,您将获得 3000 毫秒的超时,因为无法首先打开您的连接。
    • 但我得到的错误是关于读取超时:feign.RetryableException: Read timed out executing POSTCaused by: java.net.SocketTimeoutException: Read timed out
    • 我编辑了我的答案,查看它。当您将多个 feign 客户端与 hystrix 一起使用时,我会向您推荐一个配置类。仍然可以使用 application.yml,但很难维护,因为 hystrix 需要签名的方法作为命令名称(例如:FooFeignRepository#bar(String,String)),而 feign builder 可以自动执行此操作。
    猜你喜欢
    • 1970-01-01
    • 2015-02-12
    • 1970-01-01
    • 2018-06-08
    • 2011-06-06
    • 1970-01-01
    • 2011-11-12
    • 2020-12-09
    • 2011-03-09
    相关资源
    最近更新 更多