SpringCloud Feign的重试功能理解

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

你可能感兴趣的:(springcloud)