/Users/xixicat/.m2/repository/io/github/openfeign/feign-core/9.3.1/feign-core-9.3.1-sources.jar!/feign/Retryer.javajava
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; }
/Users/xixicat/.m2/repository/io/github/openfeign/feign-core/9.3.1/feign-core-9.3.1-sources.jar!/feign/Retryer.javanginx
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,即把第一次的請求也算上去了,先執行attempt >= maxAttempts判斷,再執行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.javagit
@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); } }
輸出github
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.javaspring
public Options(int connectTimeoutMillis, int readTimeoutMillis) { this.connectTimeoutMillis = connectTimeoutMillis; this.readTimeoutMillis = readTimeoutMillis; } public Options() { this(10 * 1000, 60 * 1000); }
@Bean Request.Options feignOptions() { return new Request.Options(/**connectTimeoutMillis**/1 * 1000, /** readTimeoutMillis **/1 * 1000); }
@Bean Retryer feignRetryer() { return Retryer.NEVER_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)
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)
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的參數,並且要確保反向代理,好比nginx的proxy_connect_timeout以及proxy_read_timeout要大於feign的配置才能見效,否則對外部用戶感知到的仍是nginx的504 Gateway Time-out,起不到fallback的效果。ide