Spring Cloud Config Client 超時與重試

簡介

有時客戶端需要在 config server 無響應時進行重試,以給 config server 時間進行恢復。利用 spring 提供的重試組件,我們可以方便的配置重試機制,包括重試間隔,重試次數等。

項目源碼

Gitee碼雲

爲 web 項目添加依賴

開啓客戶端重試功能需要兩個新依賴,spring-retryspring-boot-starter-aop,把如下代碼添加到 web 項目的 pom.xml 文件中:

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>1.2.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

然後在 bootstrap.yml 文件中添加如下配置:

spring:
  application:
    name: web-client
  cloud:
    config:
      uri: http://localhost:8888
      fail-fast: true
      retry:
        initial-interval: 1000
        max-attempts: 6
        max-interval: 2000
        multiplier: 1.1

首先把 spring.cloud.config.fail-fast 爲true,即在獲取不到遠程配置時,立即失敗,但是用下邊的配置進行重試。

spring.cloud.config.retry 所有子項均爲默認值:

  • initial-interval: 最初重試間隔爲 1000 毫秒
  • max-attempts: 最多重試 6 次
  • max-interval: 最長重試間隔爲 2000 毫秒
  • multiplier: 每次重試失敗後,重試間隔所增加的倍數

測試

如果使用了本教程的項目,我們需要首先啓動 configserver 項目,然後再啓動 registry 項目開啓 eureka,因爲 web 客戶端使用了 eureka 服務,之後關閉 configserver,然後啓動 web 項目,會看到如下 log:

2018-05-15 16:04:58.421  INFO 2663 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://localhost:8888

重試 6 次失敗後,客戶端啓動失敗,如果中途開啓 configserver,則 web 客戶端啓動成功。

細粒度控制重試

我們可以在代碼中實現更精細的控制重試機制,在 web 項目中創建一個新的 java 類 cn.zxuqian.configurations.RetryConfiguration,添加如下代碼:

package cn.zxuqian.configurations;

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;

public class RetryConfiguration {
    private static Logger log = LoggerFactory.getLogger(RetryConfiguration.class);

    @Bean
    @ConditionalOnMissingBean(name = "configServerRetryInterceptor")
    public RetryOperationsInterceptor configServerRetryInterceptor() {
        log.info(String.format(
                "configServerRetryInterceptor: Changing backOffOptions " +
                        "to initial: %s, multiplier: %s, maxInterval: %s",
                1000, 1.2, 5000));
        return RetryInterceptorBuilder
                .stateless()
                .backOffOptions(1000, 1.2, 5000)
                .maxAttempts(10)
                .build();
    }
}

這裏我們定義了configServerRetryInterceptor方法用於 Spring Retry 使用我們自定義的重試攔截器。方法使用 RetryInterceptorBuilder 按要求創建了一個 stateless 的 RetryOperationsInterceptor,並設置了初始重試間隔爲 1000 毫秒,增加倍數爲 1.2 倍,最大重試間隔爲 5000 毫秒,最大重試次數爲 10 次,builder 還提供了諸如配置重試機制之類的接口,有興趣的讀者可自行研究。

@ConditionalOnMissingBean 標明當 BeanFactory 中沒有名爲 configServerRetryInterceptor 的 bean 時才匹配此 Bean。

最後在 src/main/resources/META-INF/ (沒有可創建此文件夾) 新建一個 spring.factories 文件,指定我們剛創建類爲啓動時的配置,以在獲取遠程配置之前生效:

org.springframework.cloud.bootstrap.BootstrapConfiguration=cn.zxuqian.configurations.RetryConfiguration

測試

最後在關閉 configserver 的條件下啓動 web 項目,然後就會看到重試十次之後,項目啓動失敗。

歡迎訪問我的博客:張旭乾的博客

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章