超时配置
我们发现feign、ribbon、hystrix中都有超时时间配置,每个组件中超时的具体含义是什么?在三者结合协作后,又应该如何配置?
Feign
超时配置
feign中的超时配置,针对的是一次请求时的连接时间和读取时间。
- 执行一次请求的最长时间 = feign连接超时+feign读取超时
超时配置由Feign实例中的Options对象设置
private Options options = new Options();
默认配置下,连接超时时间是10S,读取超时时间是60S。
public Options() {
this(10, TimeUnit.SECONDS, 60, TimeUnit.SECONDS, true);
}
重试机制
feign中还存在重试机制,重试里有一个间隔时间。在没有启用重试时,一个请求就只执行一次,完成一个请求的最长时间就是执行一次请求的最长时间。在重试策略启用时,一个请求可以经重试策略执行多次,完成一个请求的最长时间如下
- 完成一个请求的最长时间 = (feign连接超时+feign读取超时)+ feign重试次数 * (feign重试间隔时间 + feign连接超时+feign读取超时)
重试配置由Feign实例中的Retryer对象设置
private Retryer retryer = new Retryer.Default();
默认配置下,最小间隔时间为100ms,最大间隔时间1s,最多执行5次(即失败后最多再重试4次)。
public Default() {
this(100, SECONDS.toMillis(1), 5);
}
Ribbon
我们在feign中,Client用于请求发送,而ribbon则继承、扩展了Client,提供了一个新的实现LoadBalancerFeignClient,所以请求的发送执行其实是交由ribbon完成了。
超时配置
ribbon中的超时配置,同样针对的是一次请求时的连接时间和读取时间。但其配置逻辑不同,具体来说,
-
如果feign中没有进行超时配置,那么使用Ribbon的超时配置。
- 如果ribbon没有进行超时配置,那就使用默认的配置。默认配置下,连超超时时间是1000ms,读取超时时间是1000ms。
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; }
-
如果feign中进行了超时配置,那么就使用feign的配置。
详细的逻辑见LoadBalancerFeignClient.getClientConfig()方法。
IClientConfig getClientConfig(Request.Options options, String clientName) {
IClientConfig requestConfig;
// DEFAULT_OPTIONS是一个静态对象
if (options == DEFAULT_OPTIONS) {
// 使用ribbon的超时配置
requestConfig = this.clientFactory.getClientConfig(clientName);
}
else {
// 使用feign的超时配置
requestConfig = new FeignOptionsClientConfig(options);
}
return requestConfig;
}
DEFAULT_OPTIONS对象在FeignRibbonClientAutoConfiguration中进行了注入
@Bean
@ConditionalOnMissingBean
public Request.Options feignRequestOptions() {
return LoadBalancerFeignClient.DEFAULT_OPTIONS;
}
使用feign配置的情况下,ribbon执行一次请求的最长时间如下
- 执行一次请求的最长时间 = (feign连接超时+feign读取超时)
重试机制
ribbon中也存在重试机制,只是默认未启用,其重试时没有间隔时间,因为可以配置策略,在其它实例上进行重试。如果启用重试的话,ribbon中一次请求也可以多次执行,完成一次请求的最长时间如下
- 完成一次请求的最长时间 = 重试次数 *(feign连接超时+feign读取超时)
ribbon中的重试,在网络连接失败、读取超时时才会进行,详见DefaultLoadBalancerRetryHandler。
public class DefaultLoadBalancerRetryHandler implements RetryHandler { @SuppressWarnings("unchecked") private List<Class<? extends Throwable>> retriable = Lists.<Class<? extends Throwable>>newArrayList(ConnectException.class, SocketTimeoutException.class); @SuppressWarnings("unchecked") private List<Class<? extends Throwable>> circuitRelated = Lists.<Class<? extends Throwable>>newArrayList(SocketException.class, SocketTimeoutException.class); }
如果feign和ribbon都开启了重试机制,在发生可重试异常时,两个部分的重试机制都会生效,流程如下
- feign第一次请求执行 -> ribbon负责具体的请求发送 -> 如果发生网络异常,ribbon进行重试,如果重试次数用完还是网络异常,则抛出异常 ->feign捕获异常后进行重试,再次请求执行
在都启用重试的情况下,以feign和ribbon中都只进行一次为例,一个请求最大的执行次数如下
- 执行次数 = 1*(1+1)+ 1 *(1+1)= 2 + 2 =4
完成一个请求的最长时间为
- 完成一个请求的最长时间 = 2 * (readTimeout + connectTimeout) + feign一次重试间隔时间 + 2 * (readTimeout + connectTimeout)
实际中,启用一个重试机制就可以了。
Hystrix
hystrix中的超时时间,指的是Hystrix命令在执行远程服务调用时的最大等待时间,针对的是一个请求。请求的执行由feign和ribbon完成,hystrix不关心其中的连接超时、读取超时和重试次数,只关注于这个请求执行耗时。
在进行配置时,大于feign和ribbon中完成一个请求的最长时间即可。feign和ribbon中完成一个请求的最长时间需要根据配置来进行计算,以使用feign的超时配置举例说明
- feign和ribbon都不进行重试时,完成一个请求的最长时间 = feign连接超时+feign读取超时
- feign进行重试,ribbon不进行重试时,完成一个请求的最长时间 = (feign连接超时+feign读取超时)+ feign重试次数 * (feign重试间隔时间 + feign连接超时+feign读取超时)
默认配置下,超时时间为1000ms,自定义配置hystrix全局执行超时时间。
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 2000# 设置超时时间
标签:feign,请求,Hystrix,配置,Feign,重试,ribbon,超时,Ribbon
From: https://www.cnblogs.com/cd-along/p/18213939