零、前言

网上找的各种方法,要么是老版本的,要么无效,经过一番源码研究,终于得出了配置方案。

软件版本:

Spring Boot 2.0.4.RELEASE

Spring Cloud Finchley SR2


一、原因

网上各种的方案,都是修改超时时间,当前版本修改超时时间有3中方案:

(1) feign client

#default为全局配置,如果要单独配置每个服务,改为服务名
#默认为10s
feign.client.config.default.connectTimeout=10000
#默认为60s
feign.client.config.default.readTimeout=60000

(2)hystrix

#默认为true可不配置
#hystrix.command.default.execution.timeout.enabled=true
#默认为1s
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=6000

(3)rubbin

ribbon.ConnectTimeout=10000
ribbon.ReadTimeout=60000

这三种配置会以最小的超时时间来生效。


那么问题来了,我把这三个配置项都配置上去了,而且把值改大,服务仍然秒超时。


二、解决方案

查阅了各种资料后,发现 FeignClient的默认超时时间为10s,不会开启重试机制。

看见重点了吗,“不会开启重试机制”,没有重试,超时时间再长也没用,所以还得手动加上。

#这是默认的配置,单次请求最大时长是1s,默认重试5次
#所以如果使用默认配置,超时时间最长也就6s左右,如果要更长时间,则需要自定义了
feign.client.config.default.retryer=feign.Retryer.Default


Retryer默认配置的源码

public 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();
    }
    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);
  }
}


三、最终配置

feign.hystrix.enabled=true
#feign.client.config.default.connectTimeout=10000
#feign.client.config.default.readTimeout=60000
feign.client.config.default.retryer=feign.Retryer.Default
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=6000


赞助本站,网站的持续发展离不开你们的支持!一分也是爱ヾ(◍°∇°◍)ノ゙
 本文链接: ,花了好多脑细胞写的,转载请注明链接喔~~
登陆
      正在加载评论