文章目录
前言
本篇主要介绍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 带来了【约定大于配置】,但是,通过这次的学习告诉我们,越是约定大于配置,越是要对那些“默认配置”心里有数才行。

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

被折叠的 条评论
为什么被折叠?



