默認值
默認maxAttempts值
/Users/xixicat/.m2/repository/io/github/openfeign/feign-core/9.3.1/feign-core-9.3.1-sources.jar!/feign/Retryer.java
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;
}
retry邏輯
/Users/xixicat/.m2/repository/io/github/openfeign/feign-core/9.3.1/feign-core-9.3.1-sources.jar!/feign/Retryer.java
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();
}
sleptForMillis += interval;
}
這里attempt初始值為1,即把第一次的請求也算上去了,先執(zhí)行attempt >= maxAttempts判斷丰包,再執(zhí)行attempt++衙伶。因此maxAttempts設置為2表示重試1次图筹。
/Users/xixicat/.m2/repository/io/github/openfeign/feign-core/9.3.1/feign-core-9.3.1-sources.jar!/feign/SynchronousMethodHandler.java
@Override
public Object invoke(Object[] argv) throws Throwable {
RequestTemplate template = buildTemplateFromArgs.create(argv);
Retryer retryer = this.retryer.clone();
while (true) {
try {
return executeAndDecode(template);
} catch (RetryableException e) {
retryer.continueOrPropagate(e);
if (logLevel != Logger.Level.NONE) {
logger.logRetry(metadata.configKey(), logLevel);
}
continue;
}
}
}
關于++
@Test
public void testPlus(){
int attempt = 1;
int maxAttempts = 1;
try{
if(attempt++ == maxAttempts){
throw new RuntimeException("EXCEED");
}
}finally {
System.out.println(attempt);
}
}
輸出
2
java.lang.RuntimeException: EXCEED
at XXXTest.testPlus(XXXTest.java:50)
默認超時時間
/Users/xixicat/.m2/repository/io/github/openfeign/feign-core/9.3.1/feign-core-9.3.1-sources.jar!/feign/Request.java
public Options(int connectTimeoutMillis, int readTimeoutMillis) {
this.connectTimeoutMillis = connectTimeoutMillis;
this.readTimeoutMillis = readTimeoutMillis;
}
public Options() {
this(10 * 1000, 60 * 1000);
}
參數(shù)設置
timeout設置
@Bean
Request.Options feignOptions() {
return new Request.Options(/**connectTimeoutMillis**/1 * 1000, /** readTimeoutMillis **/1 * 1000);
}
retry配置
@Bean
Retryer feignRetryer() {
return Retryer.NEVER_RETRY;
}
響應時間
默認retry響應時間(1s connectTimeout,1s readTimeout
)
Percentage of the requests served within a certain time (ms)
50% 6718
66% 7020
75% 7371
80% 8237
90% 8404
95% 8404
98% 8404
99% 8404
100% 8404 (longest request)
不retry(1s connectTimeout,1s readTimeout
)
Percentage of the requests served within a certain time (ms)
50% 1219
66% 1230
75% 1307
80% 1485
90% 1674
95% 1674
98% 1674
99% 1674
100% 1674 (longest request)
不retry(5s connectTimeout,5s readTimeout
)
Percentage of the requests served within a certain time (ms)
50% 5561
66% 5592
75% 5653
80% 5677
90% 5778
95% 5778
98% 5778
99% 5778
100% 5778 (longest request)
小結
feign client默認的connectTimeout為10s瓣戚,readTimeout為60.單純設置timeout球碉,可能沒法立馬見效撞蜂,因為默認的retry為5次.因此盲镶,如果期望fail fast的話,需要同時自定義timeout以及retry的參數(shù)蝌诡,而且要確保反向代理溉贿,比如nginx的proxy_connect_timeout以及proxy_read_timeout要大于feign的配置才能見效,不然對外部用戶感知到的還是nginx的504 Gateway Time-out浦旱,起不到fallback的效果宇色。