How can I use bulkhead in feignClient?

1k views Asked by At

1、Can I use bulkhead pattern in feignClient?

2、I have some confusion about hystrix.


For example,if I only have three feign clients "a","b","c"。The "a" calls "b" and "c".
I know I can easily use circuit breaker with fallback parameter and some Configuration like this:

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

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

In another way,I could use @HystrixCommand to wrap my remote call with some Configuration like this:

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

In addition I can configure some parameter in @HystrixCommand or application.yml,and I also can add threadPoolKey in in @HystrixCommand


Q1:I have learn that Hystrix wrapped remote call to achieve purpose,I can understand on the latter way,but the former way likes wrapping callee?

I found in document that:

Feign will wrap all methods with a circuit break

Is this mean FeignClient seems adding @Hystrixcommand on every method in interface in essence?

Q2:If the Feign client "b" have three remote call,how can I let them run in bulkhead to avoid one method consuming all thread? to Combine the feignClient and @HystrixCommand? will them conflict?
Because I do not found the parameter likes threadPoolKey in feignClient. Auto bulkhead?

Q3:If my hystrix configuration is in application.yml ,the feignClient pattern and @HytirxCommand pattern whether have the same configuration pattern? like this:

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

but what's the follow Timeout?

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

There are 1 answers

0
Mehran Mastcheshmi On

1、Can I use bulkhead pattern in feignClient?

Java doc of setterFactory() method of HystrixFeign class says:

/**
 * 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 says:

Spring Cloud Netflix does not provide the following beans by default for feign, but still looks up beans of these types from the application context to create the feign client: • Logger.Level • Retryer • ErrorDecoder • Request.Options • Collection • SetterFactory

So we should create setterFactory and specifying thread pool there. You can create a Bean like this:

@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() ));
    };
}

but what's the follow Timeout?

Feign client timeout is similar to ribbon timeout and specifies the properties of httpconnectin but you can define different timeouts for different 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 

How did I found that? if you debug your application and put breakpoints on the following code of RetryableFeignLoadBalancer class:

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);
}

you will see these value will be used as properties of HTTPConection.pls have a look at feign.Client class.

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