Skip to content

Commit

Permalink
重构Resilience4j熔断配置
Browse files Browse the repository at this point in the history
  • Loading branch information
chentianming11 committed May 24, 2022
1 parent e7a1a5e commit 04322c7
Show file tree
Hide file tree
Showing 11 changed files with 132 additions and 373 deletions.
56 changes: 16 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,32 +199,8 @@ retrofit:
global-resilience4j-degrade:
# 是否开启
enable: false
# 滑动窗口的类型
sliding-window-type: count_based
# 窗口的大小
sliding-window-size: 100
# 在单位窗口内最少需要几次调用才能开始进行统计计算
minimum-number-of-calls: 100
# 单位时间窗口内调用失败率达到多少后会启动断路器
failure-rate-threshold: 50
# 允许断路器自动由打开状态转换为半开状态
enable-automatic-transition-from-open-to-half-open: true
# 在半开状态下允许进行正常调用的次数
permitted-number-of-calls-in-half-open-state: 10
# 断路器打开状态转换为半开状态需要等待秒数
wait-duration-in-open-state-seconds: 60
# 指定断路器应保持半开多长时间的等待持续时间,可选配置,大于1才是有效配置。
max-wait-duration-in-half-open-state-seconds: 0
# 忽略的异常类列表,只有配置值之后才会加载。
ignore-exceptions: [ ]
# 记录的异常类列表,只有配置值之后才会加载。
record-exceptions: [ ]
# 慢调用比例阈值
slow-call-rate-threshold: 100
# 慢调用阈值秒数,超过该秒数视为慢调用
slow-call-duration-threshold-seconds: 60
# 启用可写堆栈跟踪的标志
writable-stack-trace-enabled: true
# 根据该名称从Spring容器中获取CircuitBreakerConfig,作为全局熔断配置
circuit-breaker-config-bean-name: defaultCircuitBreakerConfig
```
## 高级功能
Expand All @@ -237,17 +213,16 @@ retrofit:
默认是`defaultBaseOkHttpClient`,可以按下面方式覆盖Spring配置:

```java
@Bean
@Primary
OkHttpClient defaultBaseOkHttpClient(){
@Bean
public OkHttpClient defaultBaseOkHttpClient(){
return new OkHttpClient.Builder()
.addInterceptor(chain->{
log.info("=======替换defaultBaseOkHttpClient=====");
log.info("=======替换defaultBaseOkHttpClient构建OkHttpClient=====");
return chain.proceed(chain.request());
})
.build();
}
```
```

### 注解式拦截器

Expand Down Expand Up @@ -542,15 +517,16 @@ retrofit:

```yaml
retrofit:
# 熔断降级配置
degrade:
# 熔断降级类型。默认none,表示不启用熔断降级
degrade-type: resilience4j
# 全局resilience4j降级配置
global-resilience4j-degrade:
# 是否开启
enable: true
# ...其他resilience4j全局配置
# 熔断降级配置
degrade:
# 熔断降级类型。默认none,表示不启用熔断降级
degrade-type: resilience4j
# 全局resilience4j降级配置
global-resilience4j-degrade:
# 是否开启
enable: true
# 根据该名称从Spring容器中获取CircuitBreakerConfig,作为全局熔断配置
circuit-breaker-config-bean-name: defaultCircuitBreakerConfig
```

#### 扩展熔断降级
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
Expand All @@ -34,6 +33,7 @@
import com.github.lianjiatech.retrofit.spring.boot.log.LoggingInterceptor;
import com.github.lianjiatech.retrofit.spring.boot.retry.RetryInterceptor;

import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import okhttp3.OkHttpClient;
import retrofit2.converter.jackson.JacksonConverterFactory;
Expand All @@ -51,15 +51,6 @@ public RetrofitAutoConfiguration(RetrofitProperties retrofitProperties) {
this.retrofitProperties = retrofitProperties;
}

@Configuration
public static class RetrofitProcessorAutoConfiguration {

@Bean
public static PathMatchInterceptorBdfProcessor prototypeInterceptorBdfProcessor() {
return new PathMatchInterceptorBdfProcessor();
}
}

@Bean
@ConditionalOnMissingBean
public RetrofitConfigBean retrofitConfigBean(@Autowired(required = false) RetrofitDegrade retrofitDegrade,
Expand Down Expand Up @@ -127,35 +118,17 @@ public ServiceInstanceChooser serviceInstanceChooser() {

@Bean
@ConditionalOnMissingBean
ServiceChooseInterceptor serviceChooseInterceptor(@Autowired ServiceInstanceChooser serviceInstanceChooser) {
public ServiceChooseInterceptor serviceChooseInterceptor(@Autowired ServiceInstanceChooser serviceInstanceChooser) {
return new ServiceChooseInterceptor(serviceInstanceChooser);
}

@Bean
@Primary
@ConditionalOnMissingBean(name = Constants.DEFAULT_BASE_OK_HTTP_CLIENT)
OkHttpClient defaultBaseOkHttpClient() {
public OkHttpClient defaultBaseOkHttpClient() {
return new OkHttpClient.Builder()
.build();
}

@Bean
@ConditionalOnMissingBean
@ConditionalOnClass(name = Constants.SPH_U_CLASS_NAME)
@ConditionalOnProperty(name = Constants.DEGRADE_TYPE, havingValue = RetrofitDegrade.SENTINEL)
public RetrofitDegrade sentinelRetrofitDegrade() {
return new SentinelRetrofitDegrade(retrofitProperties.getDegrade().getGlobalSentinelDegrade());
}

@Bean
@ConditionalOnMissingBean
@ConditionalOnClass(name = Constants.CIRCUIT_BREAKER_CLASS_NAME)
@ConditionalOnProperty(name = Constants.DEGRADE_TYPE, havingValue = RetrofitDegrade.RESILIENCE4J)
public RetrofitDegrade resilience4jRetrofitDegrade() {
return new Resilience4jRetrofitDegrade(CircuitBreakerRegistry.ofDefaults(),
retrofitProperties.getDegrade().getGlobalResilience4jDegrade());
}

@Bean
@ConditionalOnMissingBean
public JacksonConverterFactory jacksonConverterFactory() {
Expand All @@ -170,4 +143,57 @@ public JacksonConverterFactory jacksonConverterFactory() {
@ConditionalOnMissingBean(RetrofitFactoryBean.class)
public static class RetrofitScannerRegistrarNotFoundConfiguration {}

@Configuration
public static class RetrofitProcessorAutoConfiguration {

@Bean
public static PathMatchInterceptorBdfProcessor prototypeInterceptorBdfProcessor() {
return new PathMatchInterceptorBdfProcessor();
}
}

@Configuration
@ConditionalOnClass(name = Constants.CIRCUIT_BREAKER_CLASS_NAME)
@ConditionalOnProperty(name = Constants.DEGRADE_TYPE, havingValue = RetrofitDegrade.RESILIENCE4J)
@EnableConfigurationProperties(RetrofitProperties.class)
public static class Resilience4jConfiguration {

private final RetrofitProperties properties;

public Resilience4jConfiguration(RetrofitProperties properties) {
this.properties = properties;
}

@Bean
@ConditionalOnMissingBean
public RetrofitDegrade resilience4jRetrofitDegrade() {
return new Resilience4jRetrofitDegrade(CircuitBreakerRegistry.ofDefaults(),
properties.getDegrade().getGlobalResilience4jDegrade());
}

@Bean
@ConditionalOnMissingBean(name = Constants.DEFAULT_CIRCUIT_BREAKER_CONFIG)
public CircuitBreakerConfig defaultCircuitBreakerConfig() {
return CircuitBreakerConfig.ofDefaults();
}
}

@ConditionalOnClass(name = Constants.SPH_U_CLASS_NAME)
@ConditionalOnProperty(name = Constants.DEGRADE_TYPE, havingValue = RetrofitDegrade.SENTINEL)
@EnableConfigurationProperties(RetrofitProperties.class)
public static class SentinelConfiguration {

private final RetrofitProperties properties;

public SentinelConfiguration(RetrofitProperties properties) {
this.properties = properties;
}

@Bean
@ConditionalOnMissingBean
public RetrofitDegrade sentinelRetrofitDegrade() {
return new SentinelRetrofitDegrade(properties.getDegrade().getGlobalSentinelDegrade());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ public interface Constants {
String CIRCUIT_BREAKER_CLASS_NAME = "io.github.resilience4j.circuitbreaker.CircuitBreaker";

String RETROFIT = "retrofit";

String DEFAULT_CIRCUIT_BREAKER_CONFIG = "defaultCircuitBreakerConfig";
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.github.lianjiatech.retrofit.spring.boot.degrade.resilience4j;

import com.github.lianjiatech.retrofit.spring.boot.core.Constants;

import lombok.Data;

/**
Expand All @@ -15,70 +17,8 @@ public class GlobalResilience4jDegradeProperty {
*/
private boolean enable = false;

/**
* 滑动窗口的类型
*/
private SlidingWindowType slidingWindowType = SlidingWindowType.COUNT_BASED;

/**
* 窗口的大小
*/
private int slidingWindowSize = 100;

/**
* 在单位窗口内最少需要几次调用才能开始进行统计计算
*/
private int minimumNumberOfCalls = 100;

/**
* 单位时间窗口内调用失败率达到多少后会启动断路器
*/
private float failureRateThreshold = 50;

/**
* 允许断路器自动由打开状态转换为半开状态
*/
private boolean enableAutomaticTransitionFromOpenToHalfOpen = true;

/**
* 在半开状态下允许进行正常调用的次数
*/
private int permittedNumberOfCallsInHalfOpenState = 10;

/**
* 断路器打开状态转换为半开状态需要等待秒数
*/
private int waitDurationInOpenStateSeconds = 60;

/**
* 指定断路器应保持半开多长时间的等待持续时间,可选配置,大于1才是有效配置。
*/
private int maxWaitDurationInHalfOpenStateSeconds = 0;

/**
* 忽略的异常类列表,只有配置值之后才会加载。
*/
@SuppressWarnings("unchecked")
private Class<? extends Throwable>[] ignoreExceptions = new Class[0];

/**
* 记录的异常类列表,只有配置值之后才会加载。
*/
@SuppressWarnings("unchecked")
private Class<? extends Throwable>[] recordExceptions = new Class[0];

/**
* 慢调用比例阈值
*/
private float slowCallRateThreshold = 100;

/**
* 慢调用阈值秒数,超过该秒数视为慢调用
*/
private int slowCallDurationThresholdSeconds = 60;

/**
* 启用可写堆栈跟踪的标志
/***
* 根据该名称从Spring容器中获取CircuitBreakerConfig,作为全局熔断配置
*/
private boolean writableStackTraceEnabled = true;
private String circuitBreakerConfigBeanName = Constants.DEFAULT_CIRCUIT_BREAKER_CONFIG;
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
package com.github.lianjiatech.retrofit.spring.boot.degrade.resilience4j;

import static io.github.resilience4j.circuitbreaker.CircuitBreakerConfig.DEFAULT_FAILURE_RATE_THRESHOLD;
import static io.github.resilience4j.circuitbreaker.CircuitBreakerConfig.DEFAULT_MINIMUM_NUMBER_OF_CALLS;
import static io.github.resilience4j.circuitbreaker.CircuitBreakerConfig.DEFAULT_PERMITTED_CALLS_IN_HALF_OPEN_STATE;
import static io.github.resilience4j.circuitbreaker.CircuitBreakerConfig.DEFAULT_SLIDING_WINDOW_SIZE;
import static io.github.resilience4j.circuitbreaker.CircuitBreakerConfig.DEFAULT_SLOW_CALL_DURATION_THRESHOLD;
import static io.github.resilience4j.circuitbreaker.CircuitBreakerConfig.DEFAULT_SLOW_CALL_RATE_THRESHOLD;
import static io.github.resilience4j.circuitbreaker.CircuitBreakerConfig.DEFAULT_WAIT_DURATION_IN_HALF_OPEN_STATE;
import static io.github.resilience4j.circuitbreaker.CircuitBreakerConfig.DEFAULT_WAIT_DURATION_IN_OPEN_STATE;
import static io.github.resilience4j.circuitbreaker.CircuitBreakerConfig.DEFAULT_WRITABLE_STACK_TRACE_ENABLED;
import static io.github.resilience4j.circuitbreaker.CircuitBreakerConfig.SlidingWindowType;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import com.github.lianjiatech.retrofit.spring.boot.core.Constants;

/**
* @author [email protected]
*/
Expand All @@ -33,67 +24,7 @@
boolean enable() default true;

/**
* 滑动窗口的类型
*/
SlidingWindowType slidingWindowType() default SlidingWindowType.COUNT_BASED;

/**
* 窗口的大小
*/
int slidingWindowSize() default DEFAULT_SLIDING_WINDOW_SIZE;

/**
* 在单位窗口内最少需要几次调用才能开始进行统计计算
*/
int minimumNumberOfCalls() default DEFAULT_MINIMUM_NUMBER_OF_CALLS;

/**
* 单位时间窗口内调用失败率达到多少后会启动断路器
*/
float failureRateThreshold() default DEFAULT_FAILURE_RATE_THRESHOLD;

/**
* 允许断路器自动由打开状态转换为半开状态
*/
boolean enableAutomaticTransitionFromOpenToHalfOpen() default true;

/**
* 在半开状态下允许进行正常调用的次数
*/
int permittedNumberOfCallsInHalfOpenState() default DEFAULT_PERMITTED_CALLS_IN_HALF_OPEN_STATE;

/**
* 断路器打开状态转换为半开状态需要等待秒数
*/
int waitDurationInOpenStateSeconds() default DEFAULT_WAIT_DURATION_IN_OPEN_STATE;

/**
* 指定断路器应保持半开多长时间的等待持续时间,可选配置,大于1才是有效配置。
*/
int maxWaitDurationInHalfOpenStateSeconds() default DEFAULT_WAIT_DURATION_IN_HALF_OPEN_STATE;

/**
* 忽略的异常类列表,只有配置值之后才会加载。
*/
Class<? extends Throwable>[] ignoreExceptions() default {};

/**
* 记录的异常类列表,只有配置值之后才会加载。
*/
Class<? extends Throwable>[] recordExceptions() default {};

/**
* 慢调用比例阈值
*/
float slowCallRateThreshold() default DEFAULT_SLOW_CALL_RATE_THRESHOLD;

/**
* 慢调用阈值秒数,超过该秒数视为慢调用
*/
int slowCallDurationThresholdSeconds() default DEFAULT_SLOW_CALL_DURATION_THRESHOLD;

/**
* 启用可写堆栈跟踪的标志
* 根据该名称从Spring容器中获取CircuitBreakerConfig,作为当前接口或者方法的熔断配置
*/
boolean writableStackTraceEnabled() default DEFAULT_WRITABLE_STACK_TRACE_ENABLED;
String circuitBreakerConfigBeanName() default Constants.CIRCUIT_BREAKER_CLASS_NAME;
}
Loading

0 comments on commit 04322c7

Please sign in to comment.