系统定制开发Spring Cloud Ribbon和Feign重试机制

配置

ribbon全局配置

#Ribbon系统定制开发读取超时时间(单位:ms)ribbon.ReadTimeout=60000#Ribbon系统定制开发连接超时时间(单位:ms)ribbon.ConnectTimeout=10000#系统定制开发单服务节点重试次数ribbon.MaxAutoRetries=0#系统定制开发最大重试其他服务节点次数ribbon.MaxAutoRetriesNextServer=0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

ribbon单服务配置

sevice-id.ribbon.ReadTimeout=60000sevice-id.ribbon.ConnectTimeout=10000sevice-id.ribbon.MaxAutoRetries=0sevice-id.ribbon.MaxAutoRetriesNextServer=0
  • 1
  • 2
  • 3
  • 4

ribbon重试次数=MaxAutoRetries*(MaxAutoRetriesNextServer+1)

client配置

feign client全局配置

#Feign读取超时时间(单位:ms)feign.client.config.default.readTimeout=60000#Feign连接超时时间(单位:ms)feign.client.config.default.connectTimeout=10000
  • 1
  • 2
  • 3
  • 4

feign client单服务配置

service-id.feign.client.config.default.readTimeout=60000service-id.feign.client.config.default.connectTimeout=10000
  • 1
  • 2

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);    }  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

默认的连接时间为10s,读取时间为60s,也可以通过重写FeignClient的config配置类文件的Options方法进行配置

	@Bean    public Options options(){        return new Request.Options(1*1000,10*1000);    }
  • 1
  • 2
  • 3
  • 4

如果同时配置了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;	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Feign重试机制

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. <br>     * 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);    }  }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78

默认是重试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);    }
  • 1
  • 2
  • 3
  • 4

tips:Feign 和 Ribbon重试,其实二者的重试机制相互独立,并无联系。如果一个http请求,如果feign和ribbon都配置了重试机制,请求总次数 n (计算公式)为Feign 和 Ribbon 配置参数的笛卡尔积。
计算公式:n(请求总次数)=feign(默认5次) * (MaxAutoRetries+1)*(MaxAutoRetriesNextServer+1)
注意:+1是代表ribbon本身默认的请求
feign的重试机制相对来说比较鸡肋,使用Feign 的时候一般会关闭该功能。Ribbon的重试机制默认配置为0,也就是默认是去除重试机制的。

hystrix配置

#开启feign的fallback功能feign.hystrix.enabled=true#默认hystrix处理超时时长hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=60000
  • 1
  • 2
  • 3
  • 4

如果超过hystrix处理时间会直接抛出hystrix的异常:

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发