前言
请求远程接口失败时,会进入到重试策略。
一、Retryer
1、Retryer 接口
public interface Retryer extends Cloneable { /** * if retry is permitted, return (possibly after sleeping). Otherwise propagate the exception. * 在休眠后执行重试,或抛出异常 */ void continueOrPropagate(RetryableException e); Retryer clone(); } 1234567891011
2、默认不进行重试 NEVER_RETRY
Retryer NEVER_RETRY = new Retryer() { @Override public void continueOrPropagate(RetryableException e) { //直接抛出异常 throw e; } @Override public Retryer clone() { return this; } }; 12345678910111213
在 FeignClientsConfiguration 中 定义了默认的重试策略
@Bean@ConditionalOnMissingBeanpublic Retryer feignRetryer() {return Retryer.NEVER_RETRY;} 12345
二、Default
feign 里定义的默认重试策略
class Default implements Retryer {//最大重试次数 private final int maxAttempts; //重试周期 private final long period; //重试最大周期 private final long maxPeriod; //当前重试次数 int attempt; //休眠总时间 long sleptForMillis;public void continueOrPropagate(RetryableException e) { //达到了最大重试次数,抛异常 if (attempt++ >= maxAttempts) { throw e; } long interval; if (e.retryAfter() != null) { //根据 RetryableException 里 retryAfter 计算时间间隔 interval = e.retryAfter().getTime() - currentTimeMillis(); //不能超过 maxPeriod 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; } }
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960注册Default
@Configuration public class CustomFeignClientsConfiguration { @Bean public Retryer feignRetryer() { return new Retryer.Default(); } } 12345678