简介
有时客户端需要在 config server 无响应时进行重试, 以给 config server 时间进行恢复. 利用 spring 提供的重试组件, 我们可以方便的配置重试机制, 包括重试间隔, 重试次数等.
项目源码
Gitee 码云 https://gitee.com/zxuqian/spring-cloud/tree/config-client-retry
为 web 项目添加依赖
开启客户端重试功能需要两个新依赖, spring-retry 和
spring-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 项目, 然后就会看到重试十次之后, 项目启动失败.
欢迎访问我的博客: 张旭乾的博客 http://zxuqian.cn/spring-cloud-config-retry/
来源: https://juejin.im/post/5afa9af1518825429c595f27