服務網關zuul
服務重試配置(學習筆記2020.03.13)
前言:
集成網關服務,內部所有的其他微服務的調用,都將通過網關路由轉發過去,不對外直接暴露微服,對外只暴露網關服務。而且一般內部服務會部署多個實例,
zuul
內部集成了ribbon
,會自動負載均衡的方式去調用部署多臺的內部服務。爲什麼需要網關
zuul
的服務重試呢?如果沒有又有什麼區別呢?想象一個場景: 你部署了2個用戶註冊實例微服, 如果沒有配置網關重試,剛好以輪詢的方式調用到那個還沒啓動完成的用戶註冊實例微服,就會直接請求報錯!
或者集羣環境中,當某個服務不可用時,能夠自動切換到基它服務器上去,也就需要重試機制, 重試主要解決的就是這些問題!
一: 開啓zuul
網關請求重試
添加spring-retry依賴,特別注意
zuul
的重試配置需要依賴spring的retry,不然的話怎麼配置都是徒勞
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
二: 在application.yml
配置文件上開啓重試
zuul:
retryable: true
這樣配置完成所有的網關都會進行重試了
private Boolean retryable = false;
此配置默認是不開啓的
上面的配置是給所有的路由都進行重試, 也可以單獨配置那些路由進行重試!
三: 單獨給一個路由進行配置重試
zuul:
routes:
springBoot-test:
path: /test/**
serviceId: eureka-test
springBoot-Client:
path: /client/**
serviceId: eureka-client
retryable: true #單獨爲eureka-client配置重試
Zuul
內部集成了 Ribbon
來實現負載均衡,重試機制是在 Ribbon
調用執行的,可配置重試詳細規則:
ribbon:
ConnectTimeout: 5000
ReadTimeout: 5000
OkToRetryOnAllOperations: true #對所有操作請求都進行重試,默認false
MaxAutoRetries: 0 #對當前實例的重試次數,默認0
MaxAutoRetriesNextServer: 1 #對切換實例的重試次數,默認1
也可以配置某些響應狀態碼進行重試(當調用eureka-client
返回404,502的時候,進行重試,其他狀態碼不重試):
eureka-client:
ribbon:
retryableStatusCodes: 404,502
重試的時候還有補償策略和重試策略:
例如重試時間間隔(默認是沒有間隔:org.springframework.retry.backoff.NoBackOffPolicy
),我們可以實現自己的補償策略,也可以用內部實現的一些補償策略(需要定義一個bean),如指數級的補償策略(1秒,2秒,4秒類似這種指數級睡眠間隔增長,不超過10秒):
/**
* 網關配置類
* @author: zhihao
* @date: 2020/3/13
*/
@Configuration
public class MyZuulConfiguration {
@Autowired
private SpringClientFactory clientFactory;
/**
* 負載平衡重試工廠
* @return
*/
@Bean
public LoadBalancedRetryFactory loadBalancedRetryFactory() {
return new MyRibbonLoadBalancedRetryFactory(clientFactory);
}
/**
* My負載平衡重試工廠
*/
public class MyRibbonLoadBalancedRetryFactory extends RibbonLoadBalancedRetryFactory{
public MyRibbonLoadBalancedRetryFactory(SpringClientFactory clientFactory) {
super(clientFactory);
}
/**
* 重寫,retry回退補償機制規則
*
* @param service
* @return org.springframework.retry.backoff.BackOffPolicy
* @author: zhihao
* @date: 2020/3/13
*/
@Override
public BackOffPolicy createBackOffPolicy(String service) {
ExponentialBackOffPolicy exponentialBackOffPolicy = new ExponentialBackOffPolicy();
// 指數回退,第一次回退0.2s,第二次回退0.4s
exponentialBackOffPolicy.setInitialInterval(200L);
exponentialBackOffPolicy.setMultiplier(2.0);
//設置最大間隔回退時間爲30秒 默認值
exponentialBackOffPolicy.setMaxInterval(30000L);
return exponentialBackOffPolicy;
}
/**
* 重寫,ribbon重試策略
* @param service
* @param serviceInstanceChooser
* @return
*/
@Override
public LoadBalancedRetryPolicy createRetryPolicy(String service, ServiceInstanceChooser serviceInstanceChooser) {
//獲取當前客戶端默認配置
IClientConfig clientConfig = clientFactory.getClientConfig(service);
//設置MaxAutoRetries,MaxAutoRetriesNextServer 當前實例於切換的重試次數 等同於yml配置MaxAutoRetries
// `CommonClientConfigKey類中`裏面有很多重試規則可以自定義
clientConfig.set(CommonClientConfigKey.MaxAutoRetries,1);
clientConfig.set(CommonClientConfigKey.MaxAutoRetriesNextServer,1);
//等同於retryableStatusCodes設置重試狀態碼
clientConfig.set(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES,"404,502");
RibbonLoadBalancerContext lbContext = clientFactory.getLoadBalancerContext(service);
//使用客戶端配置生成`RibbonLoadBalancerContext`
lbContext.initWithNiwsConfig(clientConfig);
//創建功能區負載平衡重試策略
RibbonLoadBalancedRetryPolicy retryPolicy = new RibbonLoadBalancedRetryPolicy(service, lbContext, serviceInstanceChooser, clientConfig);
return retryPolicy;
}
}
}
到此重試的其他配置,後續有空在研究
擴展資料:
CommonClientConfigKey
類中的信息是可配置ribbon
的重試策略的key