Spring Cloud Feign和Ribbon的超时参数设置

本文详细介绍了Spring Cloud Feign和Ribbon的超时参数设置,包括Feign和Ribbon的基本概念,它们的默认配置及可能出现的坑点。在Feign中,若不设置超时,默认超时时间为1s。配置超时参数时,需同时设置connectTimeout和readTimeout。当Feign和Ribbon同时配置超时时,以Feign为准。此外,还分享了如何通过配置文件和配置类来定制超时时间。


前言

本篇主要介绍SpringCloud Fegin结合Ribbon实现负载均衡的超时参数详解及设置。Feign 自己有两个超时参数,它使用的负载均衡组件 Ribbon 本身还有相关配置。那么,这些配置的优先级是怎样的,又哪些什么坑呢?


一、SpringCloud Feign?SpringCloud Ribbon?

1、Feign 介绍

Feign是一个声明式的Web Service客户端,它使得编写Web Serivce客户端变得更加简单。我们只需要使用Feign来创建一个接口并用注解来配置它既可完成。它具备可插拔的注解支持,包括Feign注解和JAX-RS注解。Feign也支持可插拔的编码器和解码器。Spring Cloud为Feign增加了对Spring MVC注解的支持,还整合了Ribbon和Eureka来提供均衡负载的HTTP客户端实现。

3.Ribbon 介绍

Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随即连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。简单地说,Ribbon是一个客户端负载均衡器。

2.默认配置

所谓默认参数就是没有配置任何相关的超时参数,我们来看看源码里Feign默认的设置是多少:

public class DefaultClientConfigImpl implements IClientConfig {

    public static final int DEFAULT_READ_TIMEOUT = 5000;

    public static final int DEFAULT_CONNECTION_MANAGER_TIMEOUT = 2000;

    public static final int DEFAULT_CONNECT_TIMEOUT = 2000;

乍一看默认好像connectTimeou为2秒,readTimeout为5s,是不是感觉这个配置没毛病呀,哪怕我就用默认的也都能满足需求,接着我们来看,一个巨大的坑等着你来跳。


/**
 * Ribbon client default connect timeout.
 */
public static final int DEFAULT_CONNECT_TIMEOUT = 1000;
/**
 * Ribbon client default read timeout.
 */
public static final int DEFAULT_READ_TIMEOUT = 1000;
@Bean
@ConditionalOnMissingBean
public IClientConfig ribbonClientConfig() {
   DefaultClientConfigImpl config = new DefaultClientConfigImpl();
   config.loadProperties(this.name);
   config.set(CommonClientConfigKey.ConnectTimeout, DEFAULT_CONNECT_TIMEOUT);
   config.set(CommonClientConfigKey.ReadTimeout, DEFAULT_READ_TIMEOUT);
   config.set(CommonClientConfigKey.GZipPayload, DEFAULT_GZIP_PAYLOAD);
   return config;
}

我们来分析一下源码。打开 RibbonClientConfiguration 类后,会看到 DefaultClientConfigImpl 被创建出来之后,ReadTimeout 和 ConnectTimeout 被设置为 1s

4.参数设置

显然1s的超时时间是不行的,如果业务复杂点,或者数据处理比较耗时,或者网络问题,那是很容易触发超时的,那么怎么设置自定义超时时间呢?

ribbon全局配置

ribbon:  
    ReadTimeout: 5000  
    ConnectTimeout: 5000

ribbon指定服务配置

app-server为服务名

app-server:
  ribbon:
    ReadTimeout: 5000
    ConnectTimeout: 5000

Feign全局配置

有两种方法,配置文件和配置类

配置文件
可参考官方文档:https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-feign.html

feign:
  client:
    config:
      default:
        connectTimeout: 5000
        readTimeout: 5000

配置类

注册下面的bean即可:

@Bean
public static Request.Options requestOptions(ConfigurableEnvironment env) {
     return new Request.Options(10000, 10000);
}

二、坑点1 同时配置 Feign 和 Ribbon 的超时,已谁为准?

还是看源码

在 LoadBalancerFeignClient 源码中可以看到,如果 Request.Options 不是默认值,就会创建一个 FeignOptionsClientConfig 代替原来 Ribbon 的 DefaultClientConfigImpl,导致 Ribbon 的配置被 Feign 覆盖:

public class LoadBalancerFeignClient implements Client {

    IClientConfig getClientConfig(Request.Options options, String clientName) {
		IClientConfig requestConfig;
        //只要Feign的options配置不是默认的,就会使用我们的配置,
        //反之会使用DefaultClientConfigImpl的实例,这个类实例化请看上面
		if (options == DEFAULT_OPTIONS) {
			requestConfig = this.clientFactory.getClientConfig(clientName);
		} else {
			requestConfig = new FeignOptionsClientConfig(options);
		}
		return requestConfig;
	}

三、坑点2 为什么connectTimeout和readTimeout必须同时配置?

如果要配置 Feign 的读取超时,就必须同时配置连接超时,才能生效。这又是为什么呢?

打开 FeignClientFactoryBean 可以看到,只有同时设置 ConnectTimeout 和 ReadTimeout,Request.Options 才会被覆盖:

//此处,必须ConnectTimeout 和ReadTimeout都不为null才会替换新options
if (config.getConnectTimeout() != null && config.getReadTimeout() != null) {
   builder.options(new Request.Options(config.getConnectTimeout(),
         config.getReadTimeout()));
}

总结

1、Feign如果不设置默认的超时时间,默认的时间是1s。
2、配置 Feign 的读取超时,就必须同时配置连接超时,才能生效,即connectTimeout和readTimeout必须同时配置才能生效。
3、同时配置 Feign 和 Ribbon 的超时,以Feign为准
4、除了可以配置 Feign,也可以配置 Ribbon 组件的参数来修改两个超时时间。这里的坑点三是,参数首字母要大写,和 Feign 的配置不同

感想:Spring Boot 带来了【约定大于配置】,但是,通过这次的学习告诉我们,越是约定大于配置,越是要对那些“默认配置”心里有数才行。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值