使用 Netflix Feign 和 Hystrix 设置请求超时
Posted
技术标签:
【中文标题】使用 Netflix Feign 和 Hystrix 设置请求超时【英文标题】:Setting request timeout with Netflix Feign and Hystrix 【发布时间】:2016-02-06 17:00:17 【问题描述】:我正在使用 Feign 创建一个 REST 客户端。我的电话可以正常工作,但我想添加一些超时支持,而且我正在花时间弄清楚如何做到这一点。
Feign 的文档说“要将 Hystrix 与 Feign 一起使用,请将 Hystrix 模块添加到您的类路径中。然后使用 HystrixFeign 构建器。”好的,现在我有了这个:
service = HystrixFeign.builder()
.decoder(new GsonDecoder())
.target(ProjectService.class, URL_TO_BE_MOVED_TO_PROPS);
现在我所有的方法都返回 HystrixCommands,我可以执行或排队,但我仍然看不到如何配置它们。
Hystrix wiki (https://github.com/Netflix/Hystrix/wiki/Configuration) 说配置应该像这样添加到 HystrixCommand 构造函数中:
public HystrixCommandInstance(int id)
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
.withExecutionTimeoutInMilliseconds(500)));
this.id = id;
但我的命令正在由 Feign 构建/返回,所以我无权访问构造函数。
还有一点值得注意的是,Feign-Hystrix 自述文件 (https://github.com/Netflix/feign/tree/master/hystrix) 说“要将 Hystrix 与 Feign 一起使用,请将 Hystrix 模块添加到您的类路径中。然后,将 Feign 配置为使用 HystrixInvocationHandler”,但是 Google 搜索对于 HystrixInvocationHandler 将我指向非 Netflix 存储库。即使我使用了它,我也看不到如何配置 Feign 来使用它。
请告诉我我很笨,而且这非常简单,这会让我为自己解决了这个问题而感到高兴,并为自己无法解决这个问题而感到羞耻。
TL;DR:我想为我的 Feign 客户端发出的请求设置超时。怎么做?
【问题讨论】:
【参考方案1】:事实证明,您可以使用 com.netflix.config.ConfigurationManager 的实例(来自 com.netflix.archaius:archaius-core)设置 Hystrix 属性。
Feign 使用方法名称作为 HystrixCommandKeys,因此您可以使用这些名称访问它们的属性:
ConfigurationManager.getConfigInstance().setProperty("hystrix.command." + methodName + ".execution.isolation.thread.timeoutInMilliseconds", 1500);
这是假设您已经使用 HystrixFeign 来构建您的客户端,它将每个调用包装在 HystrixCommand 对象中。
为简化起见,我创建了一个方法循环,以便可以在服务范围内应用超时:
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());
【讨论】:
为我工作。我设置默认值而不是特定方法。ConfigurationManager.getConfigInstance().setProperty("hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", 5000);
这行代码到底是在哪里运行的?无论我将其设置为什么,我所有的 feign 客户端的超时时间仍然是 1000 毫秒。
我的 'configureHystrix()' 方法在我使用 HystrixFeign 构建代理后立即运行: serviceProxy = HystrixFeign.builder().client(new OkHttpClient()) .target(ProjectServiceProxy.class, config .getHostURL());配置Hystrix();
如果你的方法有参数,它们是名称的一部分,比如hystrix.command.ProjectService#someMethod(String).execution.isolation.thread.timeoutInMilliseconds
,否则设置不起作用。【参考方案2】:
经过一些调试,我设法将 Hystrix 超时设置如下:
HystrixFeign.builder()
.setterFactory(getSetterFactory())
.target(...);
// copy-paste feign.hystrix.SetterFactory.Default, just add andCommandPropertiesDefaults
private SetterFactory getSetterFactory()
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))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
.withExecutionTimeoutInMilliseconds(15000));
;
【讨论】:
以上是关于使用 Netflix Feign 和 Hystrix 设置请求超时的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 spring-cloud-netflix 和 feign 编写集成测试
Spring Cloud Netflix:使用 Feign 处理远程服务错误