如何覆盖OpenFeign的Hystrix默认配置?大多数文档都是针对SpringBoot + OpenFeign的,它有自己的特定于Spring的配置覆盖系统。
理想情况下,可以为客户端配置Hystrix核心大小,并在每个端点的基础上配置和超时。
发布于 2021-09-15 20:40:48
Hystrix OpenFeign在构建器上有一个setterFactory()方法,允许您传入在设置每个目标端点时执行的SetterFactory lambda函数:
final SetterFactory hystrixConfigurationFactory = (target, method) -> {
final String groupKey = target.name();
final String commandKey = method.getAnnotation(RequestLine.class).value();
// Configure default thread pool properties
final HystrixThreadPoolProperties.Setter hystrixThreadPoolProperties = HystrixThreadPoolProperties.Setter()
.withCoreSize(50)
.withMaximumSize(200)
.withAllowMaximumSizeToDivergeFromCoreSize(true);
return HystrixCommand.Setter
.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey))
.andCommandKey(HystrixCommandKey.Factory.asKey(commandKey))
.andThreadPoolPropertiesDefaults(hystrixThreadPoolProperties);;
};
final MyTargetClient myTargetClient = HystrixFeign.builder()
.setterFactory(hystrixConfigurationFactory)
.client(new OkHttpClient())
.encoder(new JacksonEncoder(objectMapper))
.decoder(new JacksonDecoder(objectMapper))
.target(new Target.HardCodedTarget<>(MyTargetClient.class, "customclientname", baseUrl))上面的示例使用boilerplate from the OpenFeign documentation根据目标端点函数正确地命名Hystrix键。然后,它还将默认线程池属性core size和the core size配置为所有目标函数的默认值。
但是,由于此工厂是为每个目标端点调用的,因此我们实际上可以覆盖每个端点的Hystrix配置。这方面的一个很好的用例是Hystrix超时:有时有些端点比其他端点花费的时间更长,我们需要考虑到这一点。
最简单的方法是首先创建一个注释,并将其放在需要覆盖的目标端点上:
/**
* Override Hystrix configuration for Feign targets.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface HystrixOverride {
int DEFAULT_EXECUTION_TIMEOUT = 2_000;
/**
* Execution timeout in milliseconds.
*/
int executionTimeout() default DEFAULT_EXECUTION_TIMEOUT;
}interface MyTargetClient {
@HystrixOverride(executionTimeout = 10_000)
@RequestLine("GET /rest/{storeCode}/V1/products")
Products searchProducts(@Param("storeCode") String storeCode, @QueryMap Map<String, Object> queryMap);
@RequestLine("GET /rest/{storeCode}/V1/products/{sku}")
Product getProduct(@Param("storeCode") String storeCode, @Param("sku") String sku);
}在上面的例子中,搜索API可能需要更长的加载时间,所以我们有一个覆盖。
但是,仅仅将覆盖注释放在目标端点函数上是不够的。我们需要返回到我们的工厂并更新它以使用注释中的数据:
final SetterFactory hystrixConfigurationFactory = (target, method) -> {
final String groupKey = target.name();
final String commandKey = method.getAnnotation(RequestLine.class).value();
// Configure per-function Hystrix configuration by referencing annotations
final HystrixCommandProperties.Setter hystrixCommandProperties = HystrixCommandProperties.Setter();
final HystrixOverride hystrixOverride = method.getAnnotation(HystrixOverride.class);
final int executionTimeout = (hystrixOverride == null)
? HystrixOverride.DEFAULT_EXECUTION_TIMEOUT
: hystrixOverride.executionTimeout();
hystrixCommandProperties.withExecutionTimeoutInMilliseconds(executionTimeout);
// Configure default thread pool properties
final HystrixThreadPoolProperties.Setter hystrixThreadPoolProperties = HystrixThreadPoolProperties.Setter()
.withCoreSize(50)
.withMaximumSize(200)
.withAllowMaximumSizeToDivergeFromCoreSize(true);
return HystrixCommand.Setter
.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey))
.andCommandKey(HystrixCommandKey.Factory.asKey(commandKey))
.andCommandPropertiesDefaults(hystrixCommandProperties)
.andThreadPoolPropertiesDefaults(hystrixThreadPoolProperties);;
};上面的代码检查覆盖注释是否存在,然后使用该注释中的数据为该目标端点配置执行超时。如果不存在替代,则将改用HystrixOverride端点的默认值。最后,将得到的hystrixCommandProperties变量插入到整个HystrixCommand.Setter中。
https://stackoverflow.com/questions/69199540
复制相似问题