OpenFeign + Hystrix - Different timeout for different clients

Viewed 725

I have Hystrix working with Feign in my Spring Boot Application.

I have set the default timeout for Hystrix to 10000ms with:

feign:
  hystrix:
    enabled: true

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 10000

The problem is I have this one client, lets call it HeavyClient, that is a heavy call that sometimes takes more time and causes the circuit break. I would like to increase the timeout cap in Hystrix for this one guy only. Is it possible?

I have tried with Feign properties like:

feign:
  client:
    config:
      HeavyClient:
        connectTimeout: 30000
        readTimeout: 30000

But this doesn't work. I guess Hystrix does not check Feign properties.

I'm using:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>

Any help is appreciated, thanks!

2 Answers

After tweeking around and search more deeply I have found on this GitHub issue that default naming for Hystrix commands are something ugly like InterfaceName#methodNameSignature().

So, for instance, given the following @FeignClient:

@FeignClient(name = "heavyClient", url = "${heavyclient.url}")
public interface HeavyClient {
    
    @RequestMapping("/process/{operation}")
    public ResponseEntity<Response> process(@PathVariable("operation") String operation);
    
}

It would be configured as:

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 5000
    HeavyClient#process(String):
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 30000

Unfortunelly, this did not work for me... Not sure why... =s So to solve it, I registered a bean of type SetterFactory that would create the command keys given the @FeignClient name:

    @Bean
    public SetterFactory setterFactory() {
        return (target, method) -> HystrixCommand.Setter
                .withGroupKey(HystrixCommandGroupKey.Factory.asKey(target.name()))
                .andCommandKey(HystrixCommandKey.Factory.asKey(target.name()));
    }

And then I can use the configuration simply like:

hystrix:
  command:
    heavyClient:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 30000

CircuitBreakerNameResolver to naming circuit as HystrixCommandKey, there is a default implementation DefaultCircuitBreakerNameResolver, which output key pattern is HardCodedTarget#methodName(ParamClass), so you can customize CircuitBreakerNameResolver instead of DefaultCircuitBreakerNameResolver.

Related