Hi,我是空夜,又是一周不见!
今天来讲讲 ribbon 和 feign 中超时时间应该如何配置。
Spring Cloud 中,一般会用 feign 或者 ribbon 来进行服务调用,ribbon 还自带了负载均衡、重试机制。而feign 是基于 ribbon 的。
通常,为了保证服务的高可用,防止雪崩等问题的出现,还会引入 hystrix。hystrix 的熔断也跟超时时间有关系。
如何统筹考虑 ribbon、feign、hystrix 三者之间的关系,添加合适的配置,使得各个组件各司其职、协调合作, 是一个麻烦的问题。
想想就令人头秃。
今天我就来理清一下 ribbon、feign、hystrix 之间的超时关系。
首先有一个推论:
feign 集成了 ribbon 和 hystrix,feign 本身不带超时限制,其超时是由 ribbon 和 hystrix 控制的。
因此,我们仅需要理清 ribbon 和 hystrix 之间的超时关系即可。
下面以 ribbon 为例,分别测试在默认情况下、与 hystrix 整合使用情况下的超时情况。
1. ribbon 的默认配置
ribbon 的默认配置在 DefaultClientConfigImpl 这个类中。
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;
注意,这里出现了第一个天坑:虽然 DefaultClientConfigImpl 这个类里指定了 DEFAULT_READ_TIMEOUT 为 5000 ms,但是,debug 发现,这个默认值在构建 ribbon 的 clientConfig 时,被替换掉了。
具体如下:
在使用 ribbon 请求接口时,第一次会构建一个 IClienConfig 对象,这个方法在 RibbonClientConfiguration 类中,此时,重新设置了 ConnectTimeout、ReadTimeout、GZipPayload
public class RibbonClientConfiguration {
/**
* 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;
/**
* Ribbon client default Gzip Payload flag.
*/
public static final boolean DEFAULT_GZIP_PAYLOAD = true;
@RibbonClientName
private String name = "client";
@Autowired
private PropertiesFactory propertiesFactory;
@Bean
@ConditionalOnMissingBean
public IClientConfig ribbonClientConfig() {
DefaultClientConfigImpl config = new DefaultClientConfigImpl();
config.loadProperties(this.name);
config.set(CommonClientConfigKey