hystrixnetflix-feign

Setting request timeout with Netflix Feign and Hystrix


I'm creating a REST client using Feign. I've got my calls working, but I want to add some timeout support, and I'm having a heck of a time figuring out how to do that.

Feign's documentation says "to use Hystrix with Feign, add the Hystrix module to your classpath. Then use the HystrixFeign builder." Ok, so now I've got this:

service = HystrixFeign.builder()
                    .decoder(new GsonDecoder())
                    .target(ProjectService.class, URL_TO_BE_MOVED_TO_PROPS);

Now all of my methods are returning HystrixCommands, which I can execute or queue, but I still can't see how to configure them.

The Hystrix wiki (https://github.com/Netflix/Hystrix/wiki/Configuration) says that configuration should be added into the HystrixCommand constructor like this:

public HystrixCommandInstance(int id) {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"))
        .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
               .withExecutionTimeoutInMilliseconds(500)));
this.id = id;

But my commands are being built/return by Feign, so I don't have access to the constructors.

One more thing worth noting is that the Feign-Hystrix readme (https://github.com/Netflix/feign/tree/master/hystrix) says "To use Hystrix with Feign, add the Hystrix module to your classpath. Then, configure Feign to use the HystrixInvocationHandler," but a Google search for HystrixInvocationHandler points me toward a non-Netflix repo. Even if I used that, I don't see how to configure Feign to use it.

Please tell me I'm being dumb and that this is super simple, which will make me feel gladness that I'm past this issue, and shame for not being able to figure it out on my own.

TL;DR: I want to set timeouts on requests made by my Feign client. How do?


Solution

  • Turns out you can set Hystrix properties using an instance of com.netflix.config.ConfigurationManager (from com.netflix.archaius:archaius-core).

    Feign uses method names as HystrixCommandKeys, so you can access their properties using those names:

        ConfigurationManager.getConfigInstance().setProperty("hystrix.command." + methodName + ".execution.isolation.thread.timeoutInMilliseconds", 1500);
    

    This is assuming you've used HystrixFeign to construct your client, which wraps each call in HystrixCommand objects.

    To simplify, I created a loop of my methods so I could apply the timeout service-wide:

    private void configureHystrix() {
        Method[] methods = ProjectService.class.getMethods();
    
        String methodName;
        for(int i = 0; i < methods.length; i++) {
            methodName = methods[i].getName();
            ConfigurationManager.getConfigInstance().setProperty(String.format("hystrix.command.%s.execution.isolation.thread.timeoutInMilliseconds", methodName), config.getTimeoutInMillis());
        }
    }