首页 > 解决方案 > 如何在 feignClient 中使用隔板?

问题描述

1、feignClient中可以使用隔板模式吗?

2、我对hystrix有些疑惑。


例如,如果我只有三个 feign 客户端“a”,“b”,“c”。“a”调用“b”和“c”。我知道我可以轻松地使用带有参数和一些配置的
断路器,如下所示:fallback

@FeignClient(name = "b", fallback = bFallback.class)
protected interface HystrixClient {
  //some methods
}

@FeignClient(name = "c", fallback = cFallback.class)
protected interface HystrixClient {
  //some methods
}

以另一种方式,我可以用@HystrixCommand这样的配置来包装我的远程调用:

@HystrixCommand(fallbackMethod="getFallback") 
    public Object get(@PathVariable("id") long id) {
     //...
    }

另外我可以在@HystrixCommandor中配置一些参数application.yml也可以在里面添加threadPoolKey@HystrixCommand


Q1 : 听说Hystrix封装了remote call来达到目的,后一种方式我可以理解,但是前一种方式喜欢封装被调用者?

我在文件中发现:

Feign 将使用断路来包装所有方法

这是否意味着 FeignClient 本质上似乎在接口中的每个方法上都添加了 @Hystrixcommand ?

Q2 : 如果 Feign 客户端 "b" 有 3 个远程调用,如何让它们运行在隔板中以避免一个方法消耗所有线程? 结合feignClient 和 @HystrixCommand? 会不会冲突?<br> 因为我在feignClient中没有找到像threadPoolKey这样的参数。自动挡板?

Q3:如果我的hystrix配置在application.yml,feignClient模式和@HytirxCommand模式是否有相同的配置模式?像这样:

hystrix:
 command:
 default:
    execution:
      isolation: 
        thread:
          timeoutInMilliseconds:1000
    circuitBreaker:
      requestVolumeThreshold:10
...
...

但是接下来的超时是什么?

feign:
  client:
    config:
      feignName:
        connectTimeout: 5000
        readTimeout: 5000

标签: hystrixspring-cloud-feignnetflix-feign

解决方案


1、feignClient中可以使用隔板模式吗?

HystrixFeign 类的 setterFactory() 方法的 Java 文档说:

/**
 * Allows you to override hystrix properties such as thread pools and command keys.
 */
public Builder setterFactory(SetterFactory setterFactory) {
  this.setterFactory = setterFactory;
  return this;
}

https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-feign.html说:

Spring Cloud Netflix 默认不为 feign 提供以下 bean,但仍会从应用程序上下文中查找这些类型的 bean 以创建 feign 客户端: • Logger.Level • Retryer • ErrorDecoder • Request.Options • Collection • SetterFactory

所以我们应该创建 setterFactory 并在那里指定线程池。你可以像这样创建一个 Bean:

@Bean
public SetterFactory feignHystrixSetterFactory() {
    return (target, method) -> {
        String groupKey = target.name();
        String commandKey = Feign.configKey(target.type(), method);
        return HystrixCommand.Setter
                .withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey))
                .andCommandKey(HystrixCommandKey.Factory.asKey(commandKey))
                .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey( target.type().getSimpleName() ));
    };
}

但是接下来的超时是什么?

Feign 客户端超时类似于 Ribbon 超时,并指定了 httpconnectin 的属性,但您可以为不同的 feignclient 定义不同的超时。

feign.client.config.bar.readTimeout //this configuration will apply to bar client
feign.client.config.default.readTimeout // this configuration will apply to all feign 

我是怎么发现的?如果您调试应用程序并在 RetryableFeignLoadBalancer 类的以下代码上放置断点:

final Request.Options options;
if (configOverride != null) {
   RibbonProperties ribbon = RibbonProperties.from(configOverride);
   options = new Request.Options(ribbon.connectTimeout(this.connectTimeout),
         ribbon.readTimeout(this.readTimeout));
}
else {
   options = new Request.Options(this.connectTimeout, this.readTimeout);
}

您将看到这些值将用作 HTTPConection.pls 的属性,请查看 feign.Client 类。

connection.setConnectTimeout(options.connectTimeoutMillis());
connection.setReadTimeout(options.readTimeoutMillis());

推荐阅读