Feign默认没有开启重试,和ribbon重复,所以也不建议开启
spring-cloud-netflix-core-1.4.3.RELEASE.jar
org.springframework.cloud.netflix.ribbon.support.AbstractLoadBalancingClient
@Bean
@ConditionalOnMissingBean
public Retryer feignRetryer() {
return Retryer.NEVER_RETRY;
}
如何开启Feign的重试功能
@Configuration
public class FeignConfig {
@Bean
public Retryer feignRetryer() {
return new Retryer.Default(100, SECONDS.toMillis(1), 5);
}
}
Feign当RetryableException(RuntimeException)异常发生重试
这里还是想说明下,Feign的重试有别于ribbon重试,ribbon是当请求超时不可达发生重试
feign-core-9.5.0.jar
feign.SynchronousMethodHandler
@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) {
//Feign当RetryableException(RuntimeException)异常发生重试
retryer.continueOrPropagate(e);
if (logLevel != Logger.Level.NONE) {
logger.logRetry(metadata.configKey(), logLevel);
}
continue;
}
}
}
ribbon默认开启重试
spring-cloud-commons-1.3.2.RELEASE.jar
org.springframework.cloud.client.loadbalancer.LoadBalancerRetryProperties
@ConfigurationProperties("spring.cloud.loadbalancer.retry")
public class LoadBalancerRetryProperties {
// 默认true,开启重试
private boolean enabled = true;
}
ribbon重试默认对GET请求有效,建议不要改变,否则要对所有POST方法实现幂等
ribbon-core-2.2.4.jar
com.netflix.client.config.DefaultClientConfigImpl
public static final Boolean DEFAULT_OK_TO_RETRY_ON_ALL_OPERATIONS = Boolean.FALSE;
spring-cloud-netflix-core-1.4.3.RELEASE.jar
org.springframework.cloud.netflix.ribbon.support.AbstractLoadBalancingClient
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
super.initWithNiwsConfig(clientConfig);
this.connectTimeout = clientConfig.getPropertyAsInteger(
CommonClientConfigKey.ConnectTimeout,
RibbonClientConfiguration.DEFAULT_CONNECT_TIMEOUT);
this.readTimeout = clientConfig.getPropertyAsInteger(
CommonClientConfigKey.ReadTimeout,
RibbonClientConfiguration.DEFAULT_READ_TIMEOUT);
this.secure = clientConfig.getPropertyAsBoolean(CommonClientConfigKey.IsSecure,
false);
this.followRedirects = clientConfig.getPropertyAsBoolean(
CommonClientConfigKey.FollowRedirects,
DefaultClientConfigImpl.DEFAULT_FOLLOW_REDIRECTS);
// 关键在此的赋值
this.okToRetryOnAllOperations = clientConfig.getPropertyAsBoolean(
CommonClientConfigKey.OkToRetryOnAllOperations,
DefaultClientConfigImpl.DEFAULT_OK_TO_RETRY_ON_ALL_OPERATIONS);
}
spring-cloud-netflix-core-1.4.3.RELEASE.jar
org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicy
public boolean canRetry(LoadBalancedRetryContext context) {
HttpMethod method = context.getRequest().getMethod();
//关键在这里,如果isOkToRetryOnAllOperations是true,不管是什么请求都是true
return HttpMethod.GET == method || lbContext.isOkToRetryOnAllOperations();
}