天天看點

Spring Cloud重試機制與各元件的重試總結

SpringCloud重試機制配置

首先聲明一點,這裡的重試并不是報錯以後的重試,而是負載均衡用戶端發現遠端請求執行個體不可到達後,去重試其他執行個體。

Ribbon+RestTemplate的重試

對于整合了Ribbon的RestTemplate,例如一個RestTemplate添加了@LoadBalanced 注解:

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
 SimpleClientHttpRequestFactory simpleClientHttpRequestFactory = new SimpleClientHttpRequestFactory();
 simpleClientHttpRequestFactory.setConnectTimeout(1000);
 simpleClientHttpRequestFactory.setReadTimeout(1000);
 return new RestTemplate(simpleClientHttpRequestFactory);
}
           

在此基礎上,使用如下配置,也可實作重試:

# hystrix的逾時時間必須大于ribbon的逾時時間
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000
# 開啟重試
#zuul.retryable=true
spring.cloud.loadbalancer.retry.enabled=true
# 請求連接配接的逾時時間
ribbon.connectTimeout=2000
# 請求處理的逾時時間
ribbon.readTimeout=5000
# 對目前執行個體的重試次數
ribbon.maxAutoRetries=1
# 切換執行個體的重試次數
ribbon.maxAutoRetriesNextServer=3
# 對所有操作請求都進行重試
ribbon.okToRetryOnAllOperations=true
           

feign重試機制

feign預設是通過自己包下的Retryer進行重試配置,預設是5次

package feign;
 
import static java.util.concurrent.TimeUnit.SECONDS;
 
/**
 * Cloned for each invocation to {@link Client#execute(Request, feign.Request.Options)}.
 * Implementations may keep state to determine if retry operations should continue or not.
 */
public interface Retryer extends Cloneable {
 
 /**
  * if retry is permitted, return (possibly after sleeping). Otherwise propagate the exception.
  */
 void continueOrPropagate(RetryableException e);
 
 Retryer clone();
 
 public static 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;
  }
           

feign取消重試

1

2

3

4

@Bean

Retryer feignRetryer() {

return

Retryer.NEVER_RETRY;

}

feign請求逾時設定

@Bean
Request.Options requestOptions(ConfigurableEnvironment env){
  int ribbonReadTimeout = env.getProperty("ribbon.ReadTimeout", int.class, 6000);
  int ribbonConnectionTimeout = env.getProperty("ribbon.ConnectTimeout", int.class, 3000);
 
  return new Request.Options(ribbonConnectionTimeout, ribbonReadTimeout);
}
           

Feign的重試

Feign本身也具備重試能力,在早期的Spring Cloud中,Feign使用的是 

feign.Retryer.Default#Default()

  ,重試5次。但Feign整合了Ribbon,Ribbon也有重試的能力,此時,就可能會導緻行為的混亂。

Spring Cloud意識到了此問題,是以做了改進,将Feign的重試改為 

feign.Retryer:NEVER_RETRY

  ,如需使用Feign的重試,隻需使用Ribbon的重試配置即可。是以,對于Camden以及以後的版本,Feign的重試可使用如下屬性進行配置:

1

2

3

4

ribbon:

MaxAutoRetries:

1

MaxAutoRetriesNextServer:

2

OkToRetryOnAllOperations:

false

相關Issue可參考:https://github.com/spring-cloud/spring-cloud-netflix/issues/467

Zuul的重試

配置:

1

2

3

4

5

6

7

zuul:

# 開啟Zuul的重試

retryable:

true

ribbon:

MaxAutoRetries:

1

MaxAutoRetriesNextServer:

2

OkToRetryOnAllOperations:

false

上面我們使用 

zuul.retryable=true 

對Zuul全局開啟了重試,事實上,也可對指定路由開啟/關閉重試:

1

zuul.routes.<routename>.retryable=

true

局部配置優先級更高。

基于HTTP響應碼重試

1

2

3

clientName:

ribbon:

retryableStatusCodes:

404

,

502

注意點:

Hystrix的逾時時間必須大于逾時的時間,否則,一旦Hystrix逾時,就沒辦法繼續重試了。

一般來說,不建議将

ribbon.OkToRetryOnAllOperations 

設為true。因為一旦啟用該配置,則表示重試任何操作,包括POST請求,而由于緩存了請求體,此時可能會影響伺服器的資源。

總結

以上就是這篇文章的全部内容了,希望本文的内容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支援。

繼續閱讀