feign client的retry及超時設置

默認值

默認maxAttempts值

/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;
    }

retry邏輯

/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);
    }

參數設置

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的參數,並且要確保反向代理,好比nginx的proxy_connect_timeout以及proxy_read_timeout要大於feign的配置才能見效,否則對外部用戶感知到的仍是nginx的504 Gateway Time-out,起不到fallback的效果。ide

doc

相關文章
相關標籤/搜索