ribbon全局配置
#Ribbon读取超时时间(单位:ms)
ribbon.ReadTimeout=60000
#Ribbon连接超时时间(单位:ms)
ribbon.ConnectTimeout=10000
#单服务节点重试次数
ribbon.MaxAutoRetries=0
#最大重试其他服务节点次数
ribbon.MaxAutoRetriesNextServer=0
ribbon单服务配置
sevice-id.ribbon.ReadTimeout=60000
sevice-id.ribbon.ConnectTimeout=10000
sevice-id.ribbon.MaxAutoRetries=0
sevice-id.ribbon.MaxAutoRetriesNextServer=0
ribbon重试次数=MaxAutoRetries*(MaxAutoRetriesNextServer+1)
feign client全局配置
#Feign读取超时时间(单位:ms)
feign.client.config.default.readTimeout=60000
#Feign连接超时时间(单位:ms)
feign.client.config.default.connectTimeout=10000
feign client单服务配置
service-id.feign.client.config.default.readTimeout=60000
service-id.feign.client.config.default.connectTimeout=10000
feign的超时时间配置主要通过Request.Option类实现:
/*
* Controls the per-request settings currently required to be implemented by all {@link Client
* clients}
*/
public static class Options {
private final int connectTimeoutMillis;
private final int readTimeoutMillis;
private final boolean followRedirects;
public Options(int connectTimeoutMillis, int readTimeoutMillis, boolean followRedirects) {
this.connectTimeoutMillis = connectTimeoutMillis;
this.readTimeoutMillis = readTimeoutMillis;
this.followRedirects = followRedirects;
}
public Options(int connectTimeoutMillis, int readTimeoutMillis) {
this(connectTimeoutMillis, readTimeoutMillis, true);
}
public Options() {
this(10 * 1000, 60 * 1000);
}
}
默认的连接时间为10s,读取时间为60s,也可以通过重写FeignClient的config配置类文件的Options方法进行配置
@Bean
public Options options(){
return new Request.Options(1*1000,10*1000);
}
如果同时配置了ribbon和feign的超时时间,系统发现options的配置不是默认配置,就会生成一个新的FeignOptions覆盖原有ribbon的配置,所以feign的配置优先级会更高,最后生效的是feign,贴部分源码:
IClientConfig getClientConfig(Request.Options options, String clientName) {
IClientConfig requestConfig;
if (options == DEFAULT_OPTIONS) {
requestConfig = this.clientFactory.getClientConfig(clientName);
}
else {
requestConfig = new FeignOptionsClientConfig(options);
}
return requestConfig;
}
feign本身也有重试机制,底层通过Retryer类实现逻辑:
public interface Retryer extends Cloneable {
/**
* if retry is permitted, return (possibly after sleeping). Otherwise propagate the exception.
*/
void continueOrPropagate(RetryableException e);
Retryer clone();
class Default implements Retryer {
private final int maxAttempts;
private final long period;
private final long maxPeriod;
int attempt;
long sleptForMillis;
public Default() {
this(100, SECONDS.toMillis(1), 5);
}
public Default(long period, long maxPeriod, int maxAttempts) {
this.period = period;
this.maxPeriod = maxPeriod;
this.maxAttempts = maxAttempts;
this.attempt = 1;
}
// visible for testing;
protected long currentTimeMillis() {
return System.currentTimeMillis();
}
public void continueOrPropagate(RetryableException e) {
if (attempt++ >= maxAttempts) {
throw e;
}
long interval;
if (e.retryAfter() != null) {
interval = e.retryAfter().getTime() - currentTimeMillis();
if (interval > maxPeriod) {
interval = maxPeriod;
}
if (interval < 0) {
return;
}
} else {
interval = nextMaxInterval();
}
try {
Thread.sleep(interval);
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
throw e;
}
sleptForMillis += interval;
}
/**
* Calculates the time interval to a retry attempt.
* The interval increases exponentially with each attempt, at a rate of nextInterval *= 1.5
* (where 1.5 is the backoff factor), to the maximum interval.
*
* @return time in nanoseconds from now until the next attempt.
*/
long nextMaxInterval() {
long interval = (long) (period * Math.pow(1.5, attempt - 1));
return interval > maxPeriod ? maxPeriod : interval;
}
@Override
public Retryer clone() {
return new Default(period, maxPeriod, maxAttempts);
}
}
}
默认是重试5次,每次重试间隔100ms,最大重试间隔不超过1s
可以通过在FeignClient的config配置类中重写Retryer方法,修改Feign的重试方法和间隔时间
period重试间隔时间ms,maxPeriod最大重试间隔时间ms,maxAttempts最大重试次数(包含第一次请求,即重试次数=maxAttempts-1)
@Bean
public Retryer feignRetryer() {
return new Retryer.Default(period, maxPeriod, maxAttempts);
}
tips:Feign 和 Ribbon重试,其实二者的重试机制相互独立,并无联系。如果一个http请求,如果feign和ribbon都配置了重试机制,请求总次数 n (计算公式)为Feign 和 Ribbon 配置参数的笛卡尔积。
计算公式:n(请求总次数)=feign(默认5次) * (MaxAutoRetries+1)*(MaxAutoRetriesNextServer+1)
注意:+1是代表ribbon本身默认的请求
feign的重试机制相对来说比较鸡肋,使用Feign 的时候一般会关闭该功能。Ribbon的重试机制默认配置为0,也就是默认是去除重试机制的。
#开启feign的fallback功能
feign.hystrix.enabled=true
#默认hystrix处理超时时长
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=60000