spring-cloud-openfeign: FeignClient: can't set per client hystrix configuration

Hi

As mentione here in this issue spring-cloud/spring-cloud-netflix#1612 i’ve a problem configuring feign with hystrix fwith different hystrix setting for different feign clients.

Here my problem:

I’ve just upgraded my spring-cloud-netflix using Dalston.RELEASE and i’m trying to configure hystrix as per client as mentioned before.

my client is configured my client like this:

@FeignClient(
    name = "myclient",
    path = "/api/v1/something",
    url = "${myclient.endpoint:http://localhost:23000}",
    configuration = { ClientConfig.class })
public interface MyClient {
    
    @RequestMapping("/{country}/search")
    public ResponseEntity<Response> search(@RequestParam("param") String param);
    
}

and added a configuration in application.yml like this in order to force hystrix timeout on a specific client but not he others:

hystrix:
  command:
    myclient:
      coreSize: 3
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 1
    default:
      coreSize: 20
      maximumSize: 500
      allowMaximumSizeToDivergeFromCoreSize: true
      maxQueueSize: 50000
      queueSizeRejectionThreshold: 50000
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 1000000

But with this configuration only the default configuration is used in Feign client.

Debugging i’ve seen that org.springframework.cloud.netflix.feign.HystrixTargeter if no SetterFactor are provided use by default a standard feign.hystrix.SetterFactory. Feign by default (as mentioned here ) instrument Hystrix with a command key that includes the method name (in my case search) so the configuration will be “per single operation” and not " per client" as proof i’ve changed my configuration changing

hystrix:
    myclient: ...

to

hystrix:
     "MyClient#search(String)": ...

And, with this new weird command key, Hystrix keep non default configuration : Yuppye 😃

Right now i’ve solved my problem by providing a custom SetterFactory where i setup the command key and the goup key in same way like this:

@Bean
@ConditionalOnProperty(name = "feign.hystrix.enabled", matchIfMissing="false") 
public SetterFactory setterFactory() {
  return (target, method) -> HystrixCommand.Setter
        .withGroupKey(HystrixCommandGroupKey.Factory.asKey( target.name()))
        .andCommandKey(HystrixCommandKey.Factory.asKey( target.name()));
}

but i was wondering if

  • i’im doing something wrong
  • this behaviour is expected or not
  • in case if this is not expected maybe HystrixTargeter could auto create a custom setter with different keys (maybe commandKey can be defined as per method using HystrixCommand javanica annotation? ) in order to instrument Hystrix with some more human friendly configs 😃

Thanks for your patience

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 8
  • Comments: 17 (6 by maintainers)

Most upvoted comments

No you either set it for all Feign clients of for each method, you can set it on a class by class basis. There is no need to create a SetterFactory when using the properties.

Thanks for your contribution, but would you correct the typo please:

No , you either set it for all Feign clients ~of~ or for each method, you cannot set it on a class by class basis.

Thank you.

i think configure better in this way: ` @Configuration @ConditionalOnClass({ HystrixCommand.class, HystrixFeign.class }) public class CustomeHystrixFeignConfiguration {

@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(name = "feign.hystrix.enabled")
public Feign.Builder feignHystrixBuilder() {

	SetterFactory setterFactory = new SetterFactory() {
		@Override
		public Setter create(Target<?> target, Method method) {
			String groupKey = target.name();
			String commandKey = /* Feign.configKey(target.type(), method); */target.name();
			return HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey))
					.andCommandKey(HystrixCommandKey.Factory.asKey(commandKey));
		}
	};
	return HystrixFeign.builder().setterFactory(setterFactory);
}

} `

If you had a Feign client called MyClient and it had a method called search that took in a single String parameter than you would use the following property hystrix.command.MyClient#search(String).execution.isolation.thread.timeoutInMilliseconds