Fegin超时时间设置的优先级

feign的底层是ribbon、ribbon最终借助的是client完成服务调用,且SpringBoot即可以设置feign的超时时间。又可设置ribbon超时时间,还可以设置client(例如okhttp)超时时间。那么超时时间设置的优先级哪个高呢?

版本信息:

  • springBoot 2.2.6.RELEASE
  • springCloud Hoxton.RELEASE

Feign调用流程如下图所示:

feign调用流程.jpeg

1. 配置文件信息

### 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配置。

你可能感兴趣的:(Fegin超时时间设置的优先级)