1、問題表述
有時(shí)客戶端需要在 config server 無響應(yīng)時(shí)進(jìn)行重試,以給 config server 時(shí)間進(jìn)行恢復(fù)。利用 spring 提供的重試組件,我們可以方便的配置重試機(jī)制,包括重試間隔,重試次數(shù)等。
2、解決方法
1.粗粒度控制重試
spring:
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
config:
discovery:
enabled: true # 開啟服務(wù)發(fā)現(xiàn)
service-id: mango-config # 配置中心服務(wù)名稱
name: consumer # 對應(yīng){application}部分
profile: dev # 對應(yīng){profile}部分
label: master # 對應(yīng)git的分支,如果配置中心使用的是本地存儲,則該參數(shù)無用
#默認(rèn)false,是否啟動(dòng)快速失敗功能,功能開啟則優(yōu)先判斷config server是否正常,在獲取不到遠(yuǎn)程配置時(shí),立即失敗,但是用下邊的[retry]配置進(jìn)行重試(粗粒度)
fail-fast: true
retry:
initial-interval: 1000 #最初重試間隔為 1000 毫秒
max-attempts: 10 #最多重試 10 次
max-interval: 5000 #最長重試間隔為 5000 毫秒
multiplier: 1.2 #每次重試失敗后,重試間隔所增加的倍數(shù)
2.細(xì)粒度控制重試
package com.louis.mango.consumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.retry.interceptor.RetryInterceptorBuilder;
import org.springframework.retry.interceptor.RetryOperationsInterceptor;
/**
* 客戶端需要在 config server 無響應(yīng)時(shí)進(jìn)行重試,以給 config server 時(shí)間進(jìn)行恢復(fù)。利用 spring 提供的重試組件,配置重試機(jī)制。RetryConfiguration類實(shí)現(xiàn)細(xì)粒度控制重試機(jī)制。
* 作用:自定義重試攔截器解決異常(consul作為注冊中心時(shí)):NoSuchBeanDefinitionException:No bean named 'configServerRetryInterceptor' available
*
* Time 2019-09-27 14:51
*/
public class RetryConfiguration {
private static Logger log = LoggerFactory.getLogger(RetryConfiguration.class);
//@ConditionalOnMissingBean:當(dāng) BeanFactory 中沒有名為 configServerRetryInterceptor 的 bean 時(shí)才匹配此 Bean,對應(yīng)到bean名稱,此為細(xì)粒度控制
@ConditionalOnMissingBean(name = "configServerRetryInterceptor")
@Bean
public RetryOperationsInterceptor configServerRetryInterceptor(){
log.info(String.format(
"configServerRetryInterceptor: Changing backOffOptions " +
"to initial: %s, multiplier: %s, maxInterval: %s",
1000, 1.2, 5000));
return RetryInterceptorBuilder.stateless()
//#最初重試間隔為 1000 毫秒 #每次重試失敗后,重試間隔所增加的倍數(shù) #最長重試間隔為 5000 毫秒
.backOffOptions(1000,1.2,5000)
//#最多重試 10 次
.maxAttempts(10)
.build();
}
}
最后在 src/main/resources/META-INF/ (沒有可創(chuàng)建此文件夾) 新建一個(gè) spring.factories 文件,指定我們剛創(chuàng)建類為啟動(dòng)時(shí)的配置,以在獲取遠(yuǎn)程配置之前生效
org.springframework.cloud.bootstrap.BootstrapConfiguration=com.louis.mango.consumer.RetryConfiguration
3、測試
最后在關(guān)閉 configserver 的條件下啟動(dòng) web 項(xiàng)目,然后就會看到重試十次之后,項(xiàng)目啟動(dòng)失敗。
如果中途開啟 config server,則 web 客戶端啟動(dòng)成功。
以上方法2選1即可。