配置
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的异常: