如何微调 Spring Cloud Feign 客户端?
Posted
技术标签:
【中文标题】如何微调 Spring Cloud Feign 客户端?【英文标题】:How to fine-tune the Spring Cloud Feign client? 【发布时间】:2017-01-22 19:44:30 【问题描述】:春云doc 说:
如果 Hystrix 在类路径上,默认情况下 Feign 会包装所有方法 带断路器。
-
很好,但是如何配置 Hystrix 选项以忽略某些异常?我有一个将 HTTP 状态代码映射到异常的
ErrorDecoder
实现。如果我将@HystrixCommand
放在方法上,Feign 是否尊重这一点?
我们的要求是记录对依赖项发出的每个 HTTP 调用的各种详细信息。目前我有一个装饰的RestTemplate
可以做到这一点。根据我在代码中看到的内容以及 Dave Syer 的回答 here,Feign 不使用 RestTemplate
。那么如何满足日志记录要求呢?界面 feign.Client
看起来很有希望,尽管我不完全确定是否可以使用。
【问题讨论】:
【参考方案1】:-
Feign 不支持
@HystrixCommand
,也不支持忽略异常。我的建议是禁用 feigns hystrix 集成 (feign.hystrix.enabled=false
) 并在 feign 之外使用 hystrix。
Feign 支持RequestInterceptor
s,它会给你一个登录的地方。请参阅the docs 了解更多信息。
例子:
@FeignClient(name = "stores", configuration = StoreConfiguration.class)
public interface StoreClient
//..
@Configuration
public class StoreConfiguration
@Bean
public LoggingRequestInterceptor loggingRequestInterceptor()
return new LoggingRequestInterceptor();
【讨论】:
谢谢,我会试试上面的。你觉得我开一个feign的改进请求支持HystrixCommand
注解怎么样?
我不认为它会飞(feign 不使用 javanica,这是注释的来源),但要求能够设置忽略的异常是可以的(因为它没有实现无关紧要)。
嗯,可能需要在两个地方都完成工作,所以你没事。
好的,你的第一个建议有效,第二个无效。我需要记录通话的持续时间,RequestInterceptor
不允许我这样做。一切都是为了提出请求。【参考方案2】:
您可以编写 ErrorDecoder 并在您不希望触发断路器的异常上抛出 HystrixBadRequestException (https://github.com/Netflix/Hystrix/wiki/How-To-Use#error-propagation)
【讨论】:
谢谢。但是,我认为禁用 Feign hystrix 支持 (feign.hystrix.enabled=false
) 并在调用方方法上使用 @HystrixCommand
更简单。这就是我现在正在做的事情。
是的,使用ignoreExceptions
。【参考方案3】:
在这种情况下,我们使用自己的 mime 类型来处理异常,因此即使是错误情况也会以 http 200 响应但拥有自己的 mime 类型。然后我们可以在错误 mime 类型的情况下拦截 200er 响应,并通过从响应错误代码反序列化重新抛出与服务器端相同的异常,而不会被回退捕获。这适用于 Feign 和一些 FeignBuildwr 魔术
【讨论】:
这种方法存在不止一个问题。错误情况返回 200 违反了 HTTP 规范。这也不是 mime 类型的用途。【参考方案4】:就像@spencergibb 说的,Feign 现在不支持忽略异常,为此我开了一个enhancement request。
至于我的第二个要求,RequestInterceptor
并没有削减它,因为我需要响应时间,而RequestInterceptor
无法访问。我最终实现了feign.Client
并记录了execute
方法所花费的时间。大部分代码取自feign.Client.Default
,可惜该类不是为扩展而设计的。然后我在FeignBuilder
中使用我的自定义客户端,如下所示:
@Bean
@Scope(SCOPE_PROTOTYPE)
public Feign.Builder feignBuilder()
return HystrixFeign.builder()
.client(loggingEnabledFeignClient());
@Bean
Client loggingEnabledFeignClient()
return new LoggingEnabledFeignClient();
【讨论】:
以上是关于如何微调 Spring Cloud Feign 客户端?的主要内容,如果未能解决你的问题,请参考以下文章
spring cloud中如何通过feign调整负载均衡规则
如何使用 spring-cloud-netflix 和 feign 编写集成测试