如果您更喜欢使用配置属性来配置所有@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 和配置属性,则配置属性将获胜。
正如您在文档中所看到的,您可以为每个特定客户端设置超时。但您只为 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);
}
}
这个配置对我有用。
假冒客户:
@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>