多个Feign客户端超时配置

问题描述 投票:0回答:2

如果您更喜欢使用配置属性来配置所有@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 和配置属性,则配置属性将获胜。

java client hystrix spring-cloud-feign feign
2个回答
3
投票

正如您在文档中所看到的,您可以为每个特定客户端设置超时。但您只为 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);
    }
}

0
投票

这个配置对我有用。

假冒客户:

@FeignClient(name="test", value = "test", url = "https://api.test.com")
public interface TestClient {

    @GetMapping("/test")
    ResponseEntity<Test> getProducts();
}

application.yml:

spring:
  cloud:
    openfeign:
      client:
        config:
          default:
            connectTimeout: 20000
            readTimeout: 60000
          test:
            connectTimeout: 2000
            readTimeout: 3000

pom.xml:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.1</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
        <version>4.1.1</version>
    </dependency>
</dependencies>
© www.soinside.com 2019 - 2024. All rights reserved.