From fd59c1e3e82839f17d98b33d5b2cec69472d5c9e Mon Sep 17 00:00:00 2001 From: chentianming Date: Sun, 8 May 2022 14:32:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=A8=E5=B1=80=E7=86=94=E6=96=AD=E9=99=8D?= =?UTF-8?q?=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 114 +++++++++++++---- .../spring/boot/config/DegradeProperty.java | 17 --- .../spring/boot/config/LogProperty.java | 31 ----- .../config/RetrofitAutoConfiguration.java | 9 +- .../boot/config/RetrofitProperties.java | 11 +- .../spring/boot/degrade/DegradeProperty.java | 32 +++++ .../GlobalResilience4jDegradeProperty.java | 84 +++++++++++++ .../resilience4j/Resilience4jDegrade.java | 5 + .../Resilience4jRetrofitDegrade.java | 117 +++++++++++++++--- .../resilience4j/SlidingWindowType.java | 10 ++ .../GlobalSentinelDegradeProperty.java | 32 +++++ .../degrade/sentinel/SentinelDegrade.java | 5 + .../sentinel/SentinelRetrofitDegrade.java | 47 +++++-- .../spring/boot/log/GlobalLogProperty.java | 28 +++++ .../spring/boot/log/LoggingInterceptor.java | 33 ++--- .../GlobalRetryProperty.java} | 19 ++- .../spring/boot/retry/RetryInterceptor.java | 30 ++--- .../boot/test/degrade/DegradeR4jApi.java | 4 +- .../boot/test/degrade/DegradeSentinelApi.java | 3 +- src/test/resources/application-r4j.yml | 30 +++++ src/test/resources/application-sentinel.yml | 10 ++ src/test/resources/application.yml | 66 ++++++++-- src/test/resources/default-config.yml | 63 ++++++++-- 23 files changed, 614 insertions(+), 186 deletions(-) delete mode 100644 src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/DegradeProperty.java delete mode 100644 src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/LogProperty.java create mode 100644 src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/DegradeProperty.java create mode 100644 src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/resilience4j/GlobalResilience4jDegradeProperty.java create mode 100644 src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/resilience4j/SlidingWindowType.java create mode 100644 src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/sentinel/GlobalSentinelDegradeProperty.java create mode 100644 src/main/java/com/github/lianjiatech/retrofit/spring/boot/log/GlobalLogProperty.java rename src/main/java/com/github/lianjiatech/retrofit/spring/boot/{config/RetryProperty.java => retry/GlobalRetryProperty.java} (55%) diff --git a/README.md b/README.md index dc47271..b3a5d6f 100644 --- a/README.md +++ b/README.md @@ -169,25 +169,25 @@ retrofit: - com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory - com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory - # 日志打印配置 - log: + # 全局日志打印配置 + global-log: # 启用日志打印 - enable-global-log: true + enable: true # 全局日志打印级别 - global-log-level: info + log-level: info # 全局日志打印策略 - global-log-strategy: basic + log-strategy: basic # 重试配置 - retry: + global-retry: # 是否启用全局重试 - enable-global-retry: false + enable: false # 全局重试间隔时间 - global-interval-ms: 100 + interval-ms: 100 # 全局最大重试次数 - global-max-retries: 2 + max-retries: 2 # 全局重试规则 - global-retry-rules: + retry-rules: - response_status_not_2xx - occur_io_exception @@ -195,6 +195,47 @@ retrofit: degrade: # 熔断降级类型。默认none,表示不启用熔断降级 degrade-type: none + # 全局sentinel降级配置 + global-sentinel-degrade: + # 是否开启 + enable: false + # 各降级策略对应的阈值。平均响应时间(ms),异常比例(0-1),异常数量(1-N) + count: 1000 + # 熔断时长,单位为 s + time-window: 5 + # 降级策略(0:平均响应时间;1:异常比例;2:异常数量) + grade: 0 + + # 全局resilience4j降级配置 + 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 # 全局连接超时时间 global-connect-timeout-ms: 10000 @@ -204,6 +245,7 @@ retrofit: global-write-timeout-ms: 10000 # 全局完整调用超时时间 global-call-timeout-ms: 0 + ``` ## 高级功能 @@ -404,14 +446,14 @@ public interface HttpApi { ```yaml retrofit: - # 日志打印配置 - log: + # 全局日志打印配置 + global-log: # 启用日志打印 - enable-global-log: true + enable: true # 全局日志打印级别 - global-log-level: info + log-level: info # 全局日志打印策略 - global-log-strategy: basic + log-strategy: basic ``` **4种日志打印策略含义如下**: @@ -438,16 +480,16 @@ retrofit: 全局重试默认关闭。开启之后,所有`HTTP`请求都会按照配置参数自动重试,默认配置项如下: ```yaml - # 重试配置 - retry: + # 全局重试配置 + global-retry: # 是否启用全局重试 - enable-global-retry: false + enable: false # 全局重试间隔时间 - global-interval-ms: 100 + interval-ms: 100 # 全局最大重试次数 - global-max-retries: 2 + max-retries: 2 # 全局重试规则 - global-retry-rules: + retry-rules: - response_status_not_2xx - occur_io_exception ``` @@ -491,6 +533,21 @@ retrofit: ``` +通过以下配置可开启全局sentinel熔断降级: + +```yaml +retrofit: + # 熔断降级配置 + degrade: + # 熔断降级类型。默认none,表示不启用熔断降级 + degrade-type: sentinel + # 全局sentinel降级配置 + global-sentinel-degrade: + # 是否开启 + enable: true + # ...其他sentinel全局配置 +``` + #### resilience4j熔断降级 配置`degrade-type=resilience4j`开启。然后在相关接口或者方法上声明`@Resilience4jDegrade`即可。另外项目需要自行引入`resilience4j`依赖。 @@ -504,6 +561,21 @@ retrofit: ``` +通过以下配置可开启全局resilience4j熔断降级: + +```yaml +retrofit: + # 熔断降级配置 + degrade: + # 熔断降级类型。默认none,表示不启用熔断降级 + degrade-type: resilience4j + # 全局resilience4j降级配置 + global-resilience4j-degrade: + # 是否开启 + enable: true + # ...其他resilience4j全局配置 +``` + #### 扩展熔断降级 如果用户需要使用其他的熔断降级实现,继承`BaseRetrofitDegrade`,并将其配置`bean`即可,具体可参考`SentinelRetrofitDegrade`。 diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/DegradeProperty.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/DegradeProperty.java deleted file mode 100644 index 3bdfe04..0000000 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/DegradeProperty.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.github.lianjiatech.retrofit.spring.boot.config; - -import com.github.lianjiatech.retrofit.spring.boot.degrade.RetrofitDegrade; - -import lombok.Data; - -/** - * @author 陈添明 - */ -@Data -public class DegradeProperty { - - /** - * 熔断降级类型。默认none,表示不启用熔断降级 - */ - private String degradeType = RetrofitDegrade.NONE; -} diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/LogProperty.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/LogProperty.java deleted file mode 100644 index a9299b9..0000000 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/LogProperty.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.github.lianjiatech.retrofit.spring.boot.config; - -import com.github.lianjiatech.retrofit.spring.boot.log.LogLevel; -import com.github.lianjiatech.retrofit.spring.boot.log.LogStrategy; - -import lombok.Data; - -/** - * @author 陈添明 - */ -@Data -public class LogProperty { - - /** - * 是否启用全局日志打印 - * Enable log printing - */ - private boolean enableGlobalLog = true; - - /** - * 全局日志打印级别,支持的日志级别参见{@link LogLevel} - * Log printing level, see {@link LogLevel} for supported log levels - */ - private LogLevel globalLogLevel = LogLevel.INFO; - - /** - * 全局日志打印策略,支持的日志打印策略参见{@link LogStrategy} - * Log printing strategy, see {@link LogStrategy} for supported log printing strategies - */ - private LogStrategy globalLogStrategy = LogStrategy.BASIC; -} diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitAutoConfiguration.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitAutoConfiguration.java index 9a36a46..8bcf097 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitAutoConfiguration.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitAutoConfiguration.java @@ -121,13 +121,13 @@ public ErrorDecoderInterceptor errorDecoderInterceptor() { @Bean @ConditionalOnMissingBean public RetryInterceptor retryInterceptor() { - return new RetryInterceptor(retrofitProperties.getRetry()); + return new RetryInterceptor(retrofitProperties.getGlobalRetry()); } @Bean @ConditionalOnMissingBean public LoggingInterceptor logInterceptor() { - return new LoggingInterceptor(retrofitProperties.getLog()); + return new LoggingInterceptor(retrofitProperties.getGlobalLog()); } @Bean @@ -147,7 +147,7 @@ ServiceChooseInterceptor serviceChooseInterceptor(@Autowired ServiceInstanceChoo @ConditionalOnClass(name = "com.alibaba.csp.sentinel.SphU") @ConditionalOnProperty(name = "retrofit.degrade.degrade-type", havingValue = RetrofitDegrade.SENTINEL) public RetrofitDegrade sentinelRetrofitDegrade() { - return new SentinelRetrofitDegrade(); + return new SentinelRetrofitDegrade(retrofitProperties.getDegrade().getGlobalSentinelDegrade()); } @Bean @@ -155,7 +155,8 @@ public RetrofitDegrade sentinelRetrofitDegrade() { @ConditionalOnClass(name = "io.github.resilience4j.circuitbreaker.CircuitBreaker") @ConditionalOnProperty(name = "retrofit.degrade.degrade-type", havingValue = RetrofitDegrade.RESILIENCE4J) public RetrofitDegrade resilience4jRetrofitDegrade() { - return new Resilience4jRetrofitDegrade(CircuitBreakerRegistry.ofDefaults()); + return new Resilience4jRetrofitDegrade(CircuitBreakerRegistry.ofDefaults(), + retrofitProperties.getDegrade().getGlobalResilience4jDegrade()); } @Bean diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitProperties.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitProperties.java index aaa86c0..4fdabec 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitProperties.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitProperties.java @@ -9,6 +9,9 @@ import com.github.lianjiatech.retrofit.spring.boot.core.BasicTypeConverterFactory; import com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory; import com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory; +import com.github.lianjiatech.retrofit.spring.boot.degrade.DegradeProperty; +import com.github.lianjiatech.retrofit.spring.boot.log.GlobalLogProperty; +import com.github.lianjiatech.retrofit.spring.boot.retry.GlobalRetryProperty; import lombok.Data; import retrofit2.CallAdapter; @@ -32,11 +35,11 @@ public class RetrofitProperties { private Map pool = new LinkedHashMap<>(); /** - * 重试配置 + * 全局重试配置 * retry config */ @NestedConfigurationProperty - private RetryProperty retry = new RetryProperty(); + private GlobalRetryProperty globalRetry = new GlobalRetryProperty(); /** * 熔断降级配置 @@ -46,11 +49,11 @@ public class RetrofitProperties { private DegradeProperty degrade = new DegradeProperty(); /** - * 日志配置 + * 全局日志配置 * log config */ @NestedConfigurationProperty - private LogProperty log = new LogProperty(); + private GlobalLogProperty globalLog = new GlobalLogProperty(); /** * 全局连接超时时间 diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/DegradeProperty.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/DegradeProperty.java new file mode 100644 index 0000000..3c945b6 --- /dev/null +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/DegradeProperty.java @@ -0,0 +1,32 @@ +package com.github.lianjiatech.retrofit.spring.boot.degrade; + +import org.springframework.boot.context.properties.NestedConfigurationProperty; + +import com.github.lianjiatech.retrofit.spring.boot.degrade.resilience4j.GlobalResilience4jDegradeProperty; +import com.github.lianjiatech.retrofit.spring.boot.degrade.sentinel.GlobalSentinelDegradeProperty; + +import lombok.Data; + +/** + * @author 陈添明 + */ +@Data +public class DegradeProperty { + + /** + * 熔断降级类型。默认none,表示不启用熔断降级 + */ + private String degradeType = RetrofitDegrade.NONE; + + /** + * 全局Sentinel降级配置 + */ + @NestedConfigurationProperty + private GlobalSentinelDegradeProperty globalSentinelDegrade = new GlobalSentinelDegradeProperty(); + + /** + * 全局Resilience4j降级配置 + */ + @NestedConfigurationProperty + private GlobalResilience4jDegradeProperty globalResilience4jDegrade = new GlobalResilience4jDegradeProperty(); +} diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/resilience4j/GlobalResilience4jDegradeProperty.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/resilience4j/GlobalResilience4jDegradeProperty.java new file mode 100644 index 0000000..130f67e --- /dev/null +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/resilience4j/GlobalResilience4jDegradeProperty.java @@ -0,0 +1,84 @@ +package com.github.lianjiatech.retrofit.spring.boot.degrade.resilience4j; + +import lombok.Data; + +/** + * 全局Resilience4j降级配置 + * @author 陈添明 + * @since 2022/5/8 10:46 上午 + */ +@Data +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[] ignoreExceptions = new Class[0]; + + /** + * 记录的异常类列表,只有配置值之后才会加载。 + */ + @SuppressWarnings("unchecked") + private Class[] recordExceptions = new Class[0]; + + /** + * 慢调用比例阈值 + */ + private float slowCallRateThreshold = 100; + + /** + * 慢调用阈值秒数,超过该秒数视为慢调用 + */ + private int slowCallDurationThresholdSeconds = 60; + + /** + * 启用可写堆栈跟踪的标志 + */ + private boolean writableStackTraceEnabled = true; +} diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/resilience4j/Resilience4jDegrade.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/resilience4j/Resilience4jDegrade.java index 84902f3..66a8b8c 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/resilience4j/Resilience4jDegrade.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/resilience4j/Resilience4jDegrade.java @@ -27,6 +27,11 @@ @Inherited public @interface Resilience4jDegrade { + /** + * 是否开启 + */ + boolean enable() default true; + /** * 滑动窗口的类型 */ diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/resilience4j/Resilience4jRetrofitDegrade.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/resilience4j/Resilience4jRetrofitDegrade.java index 5b3d972..ecc4e73 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/resilience4j/Resilience4jRetrofitDegrade.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/resilience4j/Resilience4jRetrofitDegrade.java @@ -6,6 +6,8 @@ import java.util.Objects; import java.util.concurrent.TimeUnit; +import org.springframework.core.annotation.AnnotatedElementUtils; + import com.github.lianjiatech.retrofit.spring.boot.degrade.BaseRetrofitDegrade; import com.github.lianjiatech.retrofit.spring.boot.degrade.RetrofitBlockException; import com.github.lianjiatech.retrofit.spring.boot.util.AnnotationExtendUtils; @@ -26,14 +28,26 @@ public class Resilience4jRetrofitDegrade extends BaseRetrofitDegrade { protected final CircuitBreakerRegistry circuitBreakerRegistry; + protected final GlobalResilience4jDegradeProperty globalResilience4jDegradeProperty; - public Resilience4jRetrofitDegrade(CircuitBreakerRegistry circuitBreakerRegistry) { + public Resilience4jRetrofitDegrade(CircuitBreakerRegistry circuitBreakerRegistry, + GlobalResilience4jDegradeProperty globalResilience4jDegradeProperty) { this.circuitBreakerRegistry = circuitBreakerRegistry; + this.globalResilience4jDegradeProperty = globalResilience4jDegradeProperty; } @Override public boolean isEnableDegrade(Class retrofitInterface) { - return AnnotationExtendUtils.isAnnotationPresentIncludeMethod(retrofitInterface, Resilience4jDegrade.class); + if (globalResilience4jDegradeProperty.isEnable()) { + Resilience4jDegrade resilience4jDegrade = + AnnotatedElementUtils.findMergedAnnotation(retrofitInterface, Resilience4jDegrade.class); + if (resilience4jDegrade == null) { + return true; + } + return resilience4jDegrade.enable(); + } else { + return AnnotationExtendUtils.isAnnotationPresentIncludeMethod(retrofitInterface, Resilience4jDegrade.class); + } } @Override @@ -45,34 +59,97 @@ public void loadDegradeRules(Class retrofitInterface) { Resilience4jDegrade resilience4jDegrade = AnnotationExtendUtils.findMergedAnnotation(method, method.getDeclaringClass(), Resilience4jDegrade.class); - if (resilience4jDegrade == null) { + if (!needDegrade(resilience4jDegrade)) { continue; } + + CircuitBreakerConfig.SlidingWindowType slidingWindowType = + resilience4jDegrade == null + ? CircuitBreakerConfig.SlidingWindowType + .valueOf(globalResilience4jDegradeProperty.getSlidingWindowType().name()) + : resilience4jDegrade.slidingWindowType(); + int slidingWindowSize = + resilience4jDegrade == null ? globalResilience4jDegradeProperty.getSlidingWindowSize() + : resilience4jDegrade.slidingWindowSize(); + + int minimumNumberOfCalls = + resilience4jDegrade == null ? globalResilience4jDegradeProperty.getMinimumNumberOfCalls() + : resilience4jDegrade.minimumNumberOfCalls(); + + float failureRateThreshold = + resilience4jDegrade == null ? globalResilience4jDegradeProperty.getFailureRateThreshold() + : resilience4jDegrade.failureRateThreshold(); + + boolean enableAutomaticTransitionFromOpenToHalfOpen = resilience4jDegrade == null + ? globalResilience4jDegradeProperty.isEnableAutomaticTransitionFromOpenToHalfOpen() + : resilience4jDegrade.enableAutomaticTransitionFromOpenToHalfOpen(); + + int permittedNumberOfCallsInHalfOpenState = resilience4jDegrade == null + ? globalResilience4jDegradeProperty.getPermittedNumberOfCallsInHalfOpenState() + : resilience4jDegrade.permittedNumberOfCallsInHalfOpenState(); + + int waitDurationInOpenStateSeconds = + resilience4jDegrade == null ? globalResilience4jDegradeProperty.getWaitDurationInOpenStateSeconds() + : resilience4jDegrade.waitDurationInOpenStateSeconds(); + + int maxWaitDurationInHalfOpenStateSeconds = resilience4jDegrade == null + ? globalResilience4jDegradeProperty.getMaxWaitDurationInHalfOpenStateSeconds() + : resilience4jDegrade.maxWaitDurationInHalfOpenStateSeconds(); + + Class[] ignoreExceptions = + resilience4jDegrade == null ? globalResilience4jDegradeProperty.getIgnoreExceptions() + : resilience4jDegrade.ignoreExceptions(); + + Class[] recordExceptions = + resilience4jDegrade == null ? globalResilience4jDegradeProperty.getRecordExceptions() + : resilience4jDegrade.recordExceptions(); + + float slowCallRateThreshold = + resilience4jDegrade == null ? globalResilience4jDegradeProperty.getSlowCallRateThreshold() + : resilience4jDegrade.slowCallRateThreshold(); + + int slowCallDurationThresholdSeconds = resilience4jDegrade == null + ? globalResilience4jDegradeProperty.getSlowCallDurationThresholdSeconds() + : resilience4jDegrade.slowCallDurationThresholdSeconds(); + + boolean writableStackTraceEnabled = + resilience4jDegrade == null ? globalResilience4jDegradeProperty.isWritableStackTraceEnabled() + : resilience4jDegrade.writableStackTraceEnabled(); + // 断路器配置 CircuitBreakerConfig.Builder builder = CircuitBreakerConfig.custom() - .waitDurationInOpenState(Duration.ofSeconds(resilience4jDegrade.waitDurationInOpenStateSeconds())) - .permittedNumberOfCallsInHalfOpenState(resilience4jDegrade.permittedNumberOfCallsInHalfOpenState()) - .slidingWindowSize(resilience4jDegrade.slidingWindowSize()) - .slidingWindowType(resilience4jDegrade.slidingWindowType()) - .minimumNumberOfCalls(resilience4jDegrade.minimumNumberOfCalls()) - .failureRateThreshold(resilience4jDegrade.failureRateThreshold()) - .ignoreExceptions(resilience4jDegrade.ignoreExceptions()) - .recordExceptions(resilience4jDegrade.recordExceptions()) - .automaticTransitionFromOpenToHalfOpenEnabled( - resilience4jDegrade.enableAutomaticTransitionFromOpenToHalfOpen()) - .slowCallRateThreshold(resilience4jDegrade.slowCallRateThreshold()) - .slowCallDurationThreshold( - Duration.ofSeconds(resilience4jDegrade.slowCallDurationThresholdSeconds())) - .writableStackTraceEnabled(resilience4jDegrade.writableStackTraceEnabled()); - - if (resilience4jDegrade.maxWaitDurationInHalfOpenStateSeconds() > 0) { + .waitDurationInOpenState(Duration.ofSeconds(waitDurationInOpenStateSeconds)) + .permittedNumberOfCallsInHalfOpenState(permittedNumberOfCallsInHalfOpenState) + .slidingWindowSize(slidingWindowSize) + .slidingWindowType(slidingWindowType) + .minimumNumberOfCalls(minimumNumberOfCalls) + .failureRateThreshold(failureRateThreshold) + .ignoreExceptions(ignoreExceptions) + .recordExceptions(recordExceptions) + .automaticTransitionFromOpenToHalfOpenEnabled(enableAutomaticTransitionFromOpenToHalfOpen) + .slowCallRateThreshold(slowCallRateThreshold) + .slowCallDurationThreshold(Duration.ofSeconds(slowCallDurationThresholdSeconds)) + .writableStackTraceEnabled(writableStackTraceEnabled); + + if (maxWaitDurationInHalfOpenStateSeconds > 0) { builder.maxWaitDurationInHalfOpenState( - Duration.ofSeconds(resilience4jDegrade.maxWaitDurationInHalfOpenStateSeconds())); + Duration.ofSeconds(maxWaitDurationInHalfOpenStateSeconds)); } circuitBreakerRegistry.circuitBreaker(parseResourceName(method), builder.build()); } } + protected boolean needDegrade(Resilience4jDegrade resilience4jDegrade) { + if (globalResilience4jDegradeProperty.isEnable()) { + if (resilience4jDegrade == null) { + return true; + } + return resilience4jDegrade.enable(); + } else { + return resilience4jDegrade != null && resilience4jDegrade.enable(); + } + } + @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/resilience4j/SlidingWindowType.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/resilience4j/SlidingWindowType.java new file mode 100644 index 0000000..127b5a3 --- /dev/null +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/resilience4j/SlidingWindowType.java @@ -0,0 +1,10 @@ +package com.github.lianjiatech.retrofit.spring.boot.degrade.resilience4j; + +/** + * 全局Resilience4j降级配置 + * @author 陈添明 + * @since 2022/5/8 10:46 上午 + */ +public enum SlidingWindowType { + TIME_BASED, COUNT_BASED +} \ No newline at end of file diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/sentinel/GlobalSentinelDegradeProperty.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/sentinel/GlobalSentinelDegradeProperty.java new file mode 100644 index 0000000..5c8c4b9 --- /dev/null +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/sentinel/GlobalSentinelDegradeProperty.java @@ -0,0 +1,32 @@ +package com.github.lianjiatech.retrofit.spring.boot.degrade.sentinel; + +import lombok.Data; + +/** + * 全局Sentinel降级配置 + * @author 陈添明 + * @since 2022/5/8 10:45 上午 + */ +@Data +public class GlobalSentinelDegradeProperty { + + /** + * 是否开启 + */ + private boolean enable = false; + + /** + * 各降级策略对应的阈值。平均响应时间(ms),异常比例(0-1),异常数量(1-N) + */ + private double count = 1000; + + /** + * 熔断时长,单位为 s + */ + private int timeWindow = 5; + + /** + * 降级策略(0:平均响应时间;1:异常比例;2:异常数量) + */ + private int grade = 0; +} diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/sentinel/SentinelDegrade.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/sentinel/SentinelDegrade.java index 55a1612..8aa8742 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/sentinel/SentinelDegrade.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/sentinel/SentinelDegrade.java @@ -16,6 +16,11 @@ @Inherited public @interface SentinelDegrade { + /** + * 是否开启 + */ + boolean enable() default true; + /** * 各降级策略对应的阈值。平均响应时间(ms),异常比例(0-1),异常数量(1-N) */ diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/sentinel/SentinelRetrofitDegrade.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/sentinel/SentinelRetrofitDegrade.java index aadbb43..b89698c 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/sentinel/SentinelRetrofitDegrade.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/sentinel/SentinelRetrofitDegrade.java @@ -6,6 +6,8 @@ import java.util.List; import java.util.Objects; +import org.springframework.core.annotation.AnnotatedElementUtils; + import com.alibaba.csp.sentinel.Entry; import com.alibaba.csp.sentinel.EntryType; import com.alibaba.csp.sentinel.ResourceTypeConstants; @@ -26,10 +28,24 @@ */ public class SentinelRetrofitDegrade extends BaseRetrofitDegrade { + protected final GlobalSentinelDegradeProperty globalSentinelDegradeProperty; + + public SentinelRetrofitDegrade(GlobalSentinelDegradeProperty globalSentinelDegradeProperty) { + this.globalSentinelDegradeProperty = globalSentinelDegradeProperty; + } + @Override public boolean isEnableDegrade(Class retrofitInterface) { - // 类或者方法上存在@SentinelDegrade -> 允许降级 - return AnnotationExtendUtils.isAnnotationPresentIncludeMethod(retrofitInterface, SentinelDegrade.class); + if (globalSentinelDegradeProperty.isEnable()) { + SentinelDegrade sentinelDegrade = + AnnotatedElementUtils.findMergedAnnotation(retrofitInterface, SentinelDegrade.class); + if (sentinelDegrade == null) { + return true; + } + return sentinelDegrade.enable(); + } else { + return AnnotationExtendUtils.isAnnotationPresentIncludeMethod(retrofitInterface, SentinelDegrade.class); + } } @Override @@ -44,26 +60,41 @@ public void loadDegradeRules(Class retrofitInterface) { SentinelDegrade sentinelDegrade = AnnotationExtendUtils.findMergedAnnotation(method, method.getDeclaringClass(), SentinelDegrade.class); - if (sentinelDegrade == null) { + + if (!needDegrade(sentinelDegrade)) { continue; } DegradeRule degradeRule = new DegradeRule() - .setCount(sentinelDegrade.count()) - .setTimeWindow(sentinelDegrade.timeWindow()) - .setGrade(sentinelDegrade.grade()); + .setCount(sentinelDegrade == null ? globalSentinelDegradeProperty.getCount() + : sentinelDegrade.count()) + .setTimeWindow(sentinelDegrade == null ? globalSentinelDegradeProperty.getTimeWindow() + : sentinelDegrade.timeWindow()) + .setGrade(sentinelDegrade == null ? globalSentinelDegradeProperty.getGrade() + : sentinelDegrade.grade()); degradeRule.setResource(parseResourceName(method)); rules.add(degradeRule); } DegradeRuleManager.loadRules(rules); } + protected boolean needDegrade(SentinelDegrade sentinelDegrade) { + if (globalSentinelDegradeProperty.isEnable()) { + if (sentinelDegrade == null) { + return true; + } + return sentinelDegrade.enable(); + } else { + return sentinelDegrade != null && sentinelDegrade.enable(); + } + } @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Method method = Objects.requireNonNull(request.tag(Invocation.class)).method(); - if (AnnotationExtendUtils.findMergedAnnotation(method, method.getDeclaringClass(), - SentinelDegrade.class) == null) { + SentinelDegrade sentinelDegrade = AnnotationExtendUtils.findMergedAnnotation(method, method.getDeclaringClass(), + SentinelDegrade.class); + if (!needDegrade(sentinelDegrade)) { return chain.proceed(request); } String resourceName = parseResourceName(method); diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/log/GlobalLogProperty.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/log/GlobalLogProperty.java new file mode 100644 index 0000000..8460a87 --- /dev/null +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/log/GlobalLogProperty.java @@ -0,0 +1,28 @@ +package com.github.lianjiatech.retrofit.spring.boot.log; + +import lombok.Data; + +/** + * 全局日志配置 + * @author 陈添明 + */ +@Data +public class GlobalLogProperty { + + /** + * 是否启用 + */ + private boolean enable = true; + + /** + * 日志打印级别,支持的日志级别参见{@link LogLevel} + * Log printing level, see {@link LogLevel} for supported log levels + */ + private LogLevel logLevel = LogLevel.INFO; + + /** + * 日志打印策略,支持的日志打印策略参见{@link LogStrategy} + * Log printing strategy, see {@link LogStrategy} for supported log printing strategies + */ + private LogStrategy logStrategy = LogStrategy.BASIC; +} diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/log/LoggingInterceptor.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/log/LoggingInterceptor.java index 3ea3a03..4f7a621 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/log/LoggingInterceptor.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/log/LoggingInterceptor.java @@ -4,9 +4,7 @@ import java.lang.reflect.Method; import java.util.Objects; -import org.springframework.core.annotation.AnnotatedElementUtils; - -import com.github.lianjiatech.retrofit.spring.boot.config.LogProperty; +import com.github.lianjiatech.retrofit.spring.boot.util.AnnotationExtendUtils; import lombok.extern.slf4j.Slf4j; import okhttp3.Interceptor; @@ -22,47 +20,36 @@ @Slf4j public class LoggingInterceptor implements Interceptor { - protected final LogProperty logProperty; + protected final GlobalLogProperty globalLogProperty; - public LoggingInterceptor(LogProperty logProperty) { - this.logProperty = logProperty; + public LoggingInterceptor(GlobalLogProperty globalLogProperty) { + this.globalLogProperty = globalLogProperty; } @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Method method = Objects.requireNonNull(request.tag(Invocation.class)).method(); - Logging logging = AnnotatedElementUtils.findMergedAnnotation(method.getDeclaringClass(), Logging.class); + Logging logging = AnnotationExtendUtils.findMergedAnnotation(method, method.getDeclaringClass(), Logging.class); if (!needLog(logging)) { return chain.proceed(request); } - LogLevel logLevel = logging == null ? logProperty.getGlobalLogLevel() : logging.logLevel(); - LogStrategy logStrategy = logging == null ? logProperty.getGlobalLogStrategy() : logging.logStrategy(); + LogLevel logLevel = logging == null ? globalLogProperty.getLogLevel() : logging.logLevel(); + LogStrategy logStrategy = logging == null ? globalLogProperty.getLogStrategy() : logging.logStrategy(); HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(matchLogger(logLevel)); httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.valueOf(logStrategy.name())); return httpLoggingInterceptor.intercept(chain); } protected boolean needLog(Logging logging) { - if (logProperty.isEnableGlobalLog()) { - // 开启全局打印日志的情况下 - // 没配置@Logging,需要重试 + if (globalLogProperty.isEnable()) { if (logging == null) { return true; } - // 配置了@Logging,enable==true,需要打印日志 - if (logging.enable()) { - return true; - } + return logging.enable(); } else { - // 未开启全局日志打印 - // 配置了@Logging,enable==true,需要打印日志 - if (logging != null && logging.enable()) { - return true; - } + return logging != null && logging.enable(); } - // 其他情况,不需要打印日志 - return false; } protected HttpLoggingInterceptor.Logger matchLogger(LogLevel level) { diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetryProperty.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/retry/GlobalRetryProperty.java similarity index 55% rename from src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetryProperty.java rename to src/main/java/com/github/lianjiatech/retrofit/spring/boot/retry/GlobalRetryProperty.java index 673dc62..03a3bb1 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetryProperty.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/retry/GlobalRetryProperty.java @@ -1,38 +1,37 @@ -package com.github.lianjiatech.retrofit.spring.boot.config; - -import com.github.lianjiatech.retrofit.spring.boot.retry.RetryRule; +package com.github.lianjiatech.retrofit.spring.boot.retry; import lombok.Data; /** + * 全局重试配置 * @author 陈添明 */ @Data -public class RetryProperty { +public class GlobalRetryProperty { /** * 是否启用全局重试,启用的话,所有HTTP请求都会自动重试。 * 否则的话,只有被 {@link com.github.lianjiatech.retrofit.spring.boot.retry.Retry}标注的接口才会执行重试。 * 接口上Retry注解属性优先于全局配置。 */ - private boolean enableGlobalRetry = false; + private boolean enable = false; /** - * 全局最大重试次数 + * 最大重试次数 * The maximum number of retries */ - private int globalMaxRetries = 2; + private int maxRetries = 2; /** - * 全局重试时间间隔 + * 重试时间间隔 * Retry interval */ - private int globalIntervalMs = 100; + private int intervalMs = 100; /** * 重试规则,默认 响应状态码不是2xx 或者 发生IO异常 时触发重试 * Retry rule */ - private RetryRule[] globalRetryRules = {RetryRule.RESPONSE_STATUS_NOT_2XX, RetryRule.OCCUR_IO_EXCEPTION}; + private RetryRule[] retryRules = {RetryRule.RESPONSE_STATUS_NOT_2XX, RetryRule.OCCUR_IO_EXCEPTION}; } diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/retry/RetryInterceptor.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/retry/RetryInterceptor.java index e8474e3..2cec77a 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/retry/RetryInterceptor.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/retry/RetryInterceptor.java @@ -7,7 +7,6 @@ import java.util.Objects; import java.util.stream.Collectors; -import com.github.lianjiatech.retrofit.spring.boot.config.RetryProperty; import com.github.lianjiatech.retrofit.spring.boot.util.AnnotationExtendUtils; import lombok.extern.slf4j.Slf4j; @@ -22,10 +21,10 @@ @Slf4j public class RetryInterceptor implements Interceptor { - protected final RetryProperty retryProperty; + protected final GlobalRetryProperty globalRetryProperty; - public RetryInterceptor(RetryProperty retryProperty) { - this.retryProperty = retryProperty; + public RetryInterceptor(GlobalRetryProperty globalRetryProperty) { + this.globalRetryProperty = globalRetryProperty; } @Override @@ -38,32 +37,21 @@ public Response intercept(Chain chain) throws IOException { return chain.proceed(request); } // 重试 - int maxRetries = retry == null ? retryProperty.getGlobalMaxRetries() : retry.maxRetries(); - int intervalMs = retry == null ? retryProperty.getGlobalIntervalMs() : retry.intervalMs(); - RetryRule[] retryRules = retry == null ? retryProperty.getGlobalRetryRules() : retry.retryRules(); + int maxRetries = retry == null ? globalRetryProperty.getMaxRetries() : retry.maxRetries(); + int intervalMs = retry == null ? globalRetryProperty.getIntervalMs() : retry.intervalMs(); + RetryRule[] retryRules = retry == null ? globalRetryProperty.getRetryRules() : retry.retryRules(); return retryIntercept(maxRetries, intervalMs, retryRules, chain); } protected boolean needRetry(Retry retry) { - - if (retryProperty.isEnableGlobalRetry()) { - // 开启全局重试的情况下 - // 没配置@Retry,需要重试 + if (globalRetryProperty.isEnable()) { if (retry == null) { return true; } - // 配置了@Retry,enable==true,需要重试 - if (retry.enable()) { - return true; - } + return retry.enable(); } else { - // 未开启全局重试 - // 配置了@Retry,enable==true,需要重试 - if (retry != null && retry.enable()) { - return true; - } + return retry != null && retry.enable(); } - return false; } protected Response retryIntercept(int maxRetries, int intervalMs, RetryRule[] retryRules, Chain chain) { diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/degrade/DegradeR4jApi.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/degrade/DegradeR4jApi.java index 4448bce..3c4f426 100644 --- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/degrade/DegradeR4jApi.java +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/degrade/DegradeR4jApi.java @@ -18,8 +18,8 @@ * @author 陈添明 */ @RetrofitClient(baseUrl = "${test.baseUrl}", fallbackFactory = DegradeR4jApi.HttpDegradeFallbackFactory.class) -@Resilience4jDegrade(slidingWindowType = CircuitBreakerConfig.SlidingWindowType.TIME_BASED, minimumNumberOfCalls = 10, - permittedNumberOfCallsInHalfOpenState = 5) +@Resilience4jDegrade(slidingWindowType = CircuitBreakerConfig.SlidingWindowType.TIME_BASED, + failureRateThreshold = 30, minimumNumberOfCalls = 10, permittedNumberOfCallsInHalfOpenState = 5) public interface DegradeR4jApi { @GET("degrade/person1") diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/degrade/DegradeSentinelApi.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/degrade/DegradeSentinelApi.java index 7c5555e..17089e5 100644 --- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/degrade/DegradeSentinelApi.java +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/degrade/DegradeSentinelApi.java @@ -17,7 +17,6 @@ * @author 陈添明 */ @RetrofitClient(baseUrl = "${test.baseUrl}", fallbackFactory = DegradeSentinelApi.HttpDegradeFallbackFactory.class) -@SentinelDegrade public interface DegradeSentinelApi { /** @@ -27,8 +26,8 @@ public interface DegradeSentinelApi { @GET("degrade/person1") Result getPerson1(@Query("id") Long id); - @SentinelDegrade(count = 5, timeWindow = 10) @GET("degrade/person2") + @SentinelDegrade(enable = false) Result getPerson2(@Query("id") Long id); @Service diff --git a/src/test/resources/application-r4j.yml b/src/test/resources/application-r4j.yml index e240f23..ce0dc09 100644 --- a/src/test/resources/application-r4j.yml +++ b/src/test/resources/application-r4j.yml @@ -3,3 +3,33 @@ retrofit: degrade: # 熔断降级类型。默认none,表示不启用熔断降级 degrade-type: resilience4j + # 全局resilience4j降级配置 + global-resilience4j-degrade: + # 是否开启 + enable: false + # 滑动窗口的类型 + sliding-window-type: time_based + # 窗口的大小 + sliding-window-size: 100 + # 在单位窗口内最少需要几次调用才能开始进行统计计算 + minimum-number-of-calls: 10 + # 单位时间窗口内调用失败率达到多少后会启动断路器 + failure-rate-threshold: 50 + # 允许断路器自动由打开状态转换为半开状态 + enable-automatic-transition-from-open-to-half-open: true + # 在半开状态下允许进行正常调用的次数 + permitted-number-of-calls-in-half-open-state: 5 + # 断路器打开状态转换为半开状态需要等待秒数 + 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 \ No newline at end of file diff --git a/src/test/resources/application-sentinel.yml b/src/test/resources/application-sentinel.yml index 7513c5f..30285b9 100644 --- a/src/test/resources/application-sentinel.yml +++ b/src/test/resources/application-sentinel.yml @@ -3,3 +3,13 @@ retrofit: degrade: # 熔断降级类型。默认none,表示不启用熔断降级 degrade-type: sentinel + # 全局sentinel降级配置 + global-sentinel-degrade: + # 是否开启 + enable: true + # 各降级策略对应的阈值。平均响应时间(ms),异常比例(0-1),异常数量(1-N) + count: 5 + # 熔断时长,单位为 s + time-window: 10 + # 降级策略(0:平均响应时间;1:异常比例;2:异常数量) + grade: 0 \ No newline at end of file diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index 5b46259..4627471 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -18,33 +18,75 @@ retrofit: - com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory - com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory - # 日志打印配置 - log: + # 全局日志打印配置 + global-log: # 启用全局日志打印 - enable-global-log: true + enable: true # 全局日志打印级别 - global-log-level: info + log-level: info # 全局日志打印策略 - global-log-strategy: body + log-strategy: body - # 重试配置 - retry: + # 全局重试配置 + global-retry: # 是否启用全局重试 - enable-global-retry: true + enable: true # 全局重试间隔时间 - global-interval-ms: 1 + interval-ms: 1 # 全局最大重试次数 - global-max-retries: 1 + max-retries: 1 # 全局重试规则 - global-retry-rules: + retry-rules: - response_status_not_2xx - occur_io_exception # 熔断降级配置 degrade: # 熔断降级类型。默认none,表示不启用熔断降级 - degrade-type: sentinel + degrade-type: none + # 全局sentinel降级配置 + global-sentinel-degrade: + # 是否开启 + enable: false + # 各降级策略对应的阈值。平均响应时间(ms),异常比例(0-1),异常数量(1-N) + count: 1000 + # 熔断时长,单位为 s + time-window: 5 + # 降级策略(0:平均响应时间;1:异常比例;2:异常数量) + grade: 0 + + # 全局resilience4j降级配置 + 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 + # 全局连接超时时间 global-connect-timeout-ms: 5000 # 全局读取超时时间 diff --git a/src/test/resources/default-config.yml b/src/test/resources/default-config.yml index 4081ae1..776c32d 100644 --- a/src/test/resources/default-config.yml +++ b/src/test/resources/default-config.yml @@ -17,25 +17,25 @@ retrofit: - com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory - com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory - # 日志打印配置 - log: + # 全局日志打印配置 + global-log: # 启用日志打印 - enable-global-log: true + enable: true # 全局日志打印级别 - global-log-level: info + log-level: info # 全局日志打印策略 - global-log-strategy: basic + log-strategy: basic - # 重试配置 - retry: + # 全局重试配置 + global-retry: # 是否启用全局重试 - enable-global-retry: false + enable: false # 全局重试间隔时间 - global-interval-ms: 100 + interval-ms: 100 # 全局最大重试次数 - global-max-retries: 2 + max-retries: 2 # 全局重试规则 - global-retry-rules: + retry-rules: - response_status_not_2xx - occur_io_exception @@ -43,6 +43,47 @@ retrofit: degrade: # 熔断降级类型。默认none,表示不启用熔断降级 degrade-type: none + # 全局sentinel降级配置 + global-sentinel-degrade: + # 是否开启 + enable: false + # 各降级策略对应的阈值。平均响应时间(ms),异常比例(0-1),异常数量(1-N) + count: 1000 + # 熔断时长,单位为 s + time-window: 5 + # 降级策略(0:平均响应时间;1:异常比例;2:异常数量) + grade: 0 + + # 全局resilience4j降级配置 + 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 # 全局连接超时时间 global-connect-timeout-ms: 10000