现象:
分析
从上面的异常提示中可以看出,产生了一个Read time out,但是在配置文件中已经配置了read-timeout为120000ms,但是没起到任何作用,本次调用只是花费了2241ms,所以完全不应该超时。后来偶然间加上了connect-timeout配置,read-timeout配置才生效,如下代码所示:
feign:
sentinel:
enabled: true
hystrix:
enabled: false
client:
config:
default:
connect-timeout: 120000
read-timeout: 120000
根本原因是,openfeign在对超时时间判断时,将connect-timeout和 read-timeout进行&&判断,必须同时存在,否则只配置了其中的任何一个,并不会生效,部分源码如下所示(重点关注if (config.getConnectTimeout() != null && config.getReadTimeout() != null));
protected void configureUsingProperties(
FeignClientProperties.FeignClientConfiguration config,
Feign.Builder builder) {
if (config == null) {
return;
}
if (config.getLoggerLevel() != null) {
builder.logLevel(config.getLoggerLevel());
}
if (config.getConnectTimeout() != null && config.getReadTimeout() != null) {
builder.options(new Request.Options(config.getConnectTimeout(),
config.getReadTimeout()));
}
if (config.getRetryer() != null) {
Retryer retryer = getOrInstantiate(config.getRetryer());
builder.retryer(retryer);
}
if (config.getErrorDecoder() != null) {
ErrorDecoder errorDecoder = getOrInstantiate(config.getErrorDecoder());
builder.errorDecoder(errorDecoder);
}
if (config.getRequestInterceptors() != null
&& !config.getRequestInterceptors().isEmpty()) {
// this will add request interceptor to builder, not replace existing
for (Class<RequestInterceptor> bean : config.getRequestInterceptors()) {
RequestInterceptor interceptor = getOrInstantiate(bean);
builder.requestInterceptor(interceptor);
}
}
if (config.getDecode404() != null) {
if (config.getDecode404()) {
builder.decode404();
}
}
if (Objects.nonNull(config.getEncoder())) {
builder.encoder(getOrInstantiate(config.getEncoder()));
}
if (Objects.nonNull(config.getDecoder())) {
builder.decoder(getOrInstantiate(config.getDecoder()));
}
if (Objects.nonNull(config.getContract())) {
builder.contract(getOrInstantiate(config.getContract()));
}
if (Objects.nonNull(config.getExceptionPropagationPolicy())) {
builder.exceptionPropagationPolicy(config.getExceptionPropagationPolicy());
}
}
补充
引起Read timed out有很多种原因,此处只列举了一种,如果您也正好使用的是SpringCloud+OpenFeign(ribbon)+Sentinel(使用它做了调用异常处理),可以复制以下的超时配置,设定的连接和读超时时间都为12000毫秒(可以进行修改)。
feign:
sentinel:
enabled: true
hystrix:
enabled: false
client:
config:
default:
connect-timeout: 120000
read-timeout: 120000
我能想到的几种可能是,
1.同时开启了hystrix,那么需要增加hystrix的超时配置
2.同时配置 Feign 和 Ribbon 的超时,以Feign为准
3.注意connect-timeout, read-timeout参数写法,如果是驼峰模式,首字母需要大写
版权声明:本文为qq_36729737原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。