feign的底层是ribbon、ribbon最终借助的是client完成服务调用,且SpringBoot即可以设置feign的超时时间。又可设置ribbon超时时间,还可以设置client(例如okhttp)超时时间。那么超时时间设置的优先级哪个高呢?
版本信息:
- springBoot 2.2.6.RELEASE
- springCloud Hoxton.RELEASE
Feign调用流程如下图所示:
feign调用流程.jpeg1. 配置文件信息
### Feign 配置
feign:
client:
# 指定配置文件加载的顺序(全局上下文->默认上下文->指定FeignClient上下文),默认:true
# 否则按照 默认上下文->指定FeignClient上下文->全局上下文顺序加载
# 代码详见:org.springframework.cloud.openfeign.FeignClientFactoryBean.configureFeign
defaultToProperties: true
# 默认上下文
defaultConfig: myconf
config:
# 默认上下文配置
myconf:
connectTimeout: 8000
readTimeout: 120000
okhttp:
enabled: true
httpclient:
enabled: false
ribbon:
ReadTimeout: 60000 #ribbon连接超时
ConnectTimeout: 60000 #ribbon读取超时
1.1 defaultToProperties源码分析
protected void configureFeign(FeignContext context, Feign.Builder builder) {
FeignClientProperties properties = this.applicationContext
.getBean(FeignClientProperties.class);
if (properties != null) {
//默认:true
if (properties.isDefaultToProperties()) {
//通过全局上下文初始化builder对象
configureUsingConfiguration(context, builder);
//通过默认配置上下文初始化builder对象
configureUsingProperties(
properties.getConfig().get(properties.getDefaultConfig()),
builder);
//通过指定contextId初始化builder对象
configureUsingProperties(properties.getConfig().get(this.contextId),
builder);
}
else {
//通过默认配置上下文初始化builder对象
configureUsingProperties(
properties.getConfig().get(properties.getDefaultConfig()),
builder);
//通过指定contextId初始化builder对象
configureUsingProperties(properties.getConfig().get(this.contextId),
builder);
//通过全局上下文初始化builder对象
configureUsingConfiguration(context, builder);
}
}
else {
configureUsingConfiguration(context, builder);
}
}
1.2 fegin和ribbon优先级哪个高?
如下列代码所示:org.springframework.cloud.openfeign.FeignClientFactoryBean#configureUsingProperties
protected void configureUsingProperties(
FeignClientProperties.FeignClientConfiguration config,
Feign.Builder builder) {
...
if (config.getConnectTimeout() != null && config.getReadTimeout() != null) {
builder.options(new Request.Options(config.getConnectTimeout(),
config.getReadTimeout()));
}
}
若feign的配置存在,那么使用Feign的配置填充到Request.Options
中。
1.3 最终超时时间设置源码分析
源码位置:feign.okhttp.OkHttpClient#execute
public feign.Response execute(feign.Request input, feign.Request.Options options)
throws IOException {
okhttp3.OkHttpClient requestScoped;
if (delegate.connectTimeoutMillis() != options.connectTimeoutMillis()
|| delegate.readTimeoutMillis() != options.readTimeoutMillis()) {
requestScoped = delegate.newBuilder()
.connectTimeout(options.connectTimeoutMillis(), TimeUnit.MILLISECONDS)
.readTimeout(options.readTimeoutMillis(), TimeUnit.MILLISECONDS)
.followRedirects(options.isFollowRedirects())
.build();
} else {
requestScoped = delegate;
}
Request request = toOkHttpRequest(input);
Response response = requestScoped.newCall(request).execute();
return toFeignResponse(response, input).toBuilder().request(input).build();
}
判断传入的OkHttp
的超时时间是否是options
的超时时间,若不是的话,重新构建OkHttp对象,且使用options的超时时间。
由此可见—client超时时间优先级最低。
结论:feign的配置优先级高于ribbon配置。
网友评论