diff --git a/README.md b/README.md index 7d57fca..08ce5b4 100644 --- a/README.md +++ b/README.md @@ -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 ``` ## 高级功能 @@ -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(); } -``` + ``` ### 注解式拦截器 @@ -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 ``` #### 扩展熔断降级 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 ca0e11c..ac5718b 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 @@ -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; @@ -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; @@ -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, @@ -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() { @@ -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()); + } + } + } diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/Constants.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/Constants.java index 17891a7..11c38c7 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/Constants.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/Constants.java @@ -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"; } 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 index 130f67e..203e6ff 100644 --- 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 @@ -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; /** @@ -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[] ignoreExceptions = new Class[0]; - - /** - * 记录的异常类列表,只有配置值之后才会加载。 - */ - @SuppressWarnings("unchecked") - private Class[] 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; } 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 66a8b8c..a37f7eb 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 @@ -1,16 +1,5 @@ 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; @@ -18,6 +7,8 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import com.github.lianjiatech.retrofit.spring.boot.core.Constants; + /** * @author yukdawn@gmail.com */ @@ -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[] ignoreExceptions() default {}; - - /** - * 记录的异常类列表,只有配置值之后才会加载。 - */ - Class[] 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; } \ No newline at end of file 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 ecc4e73..f98beda 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 @@ -2,10 +2,12 @@ import java.io.IOException; import java.lang.reflect.Method; -import java.time.Duration; import java.util.Objects; import java.util.concurrent.TimeUnit; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; import org.springframework.core.annotation.AnnotatedElementUtils; import com.github.lianjiatech.retrofit.spring.boot.degrade.BaseRetrofitDegrade; @@ -25,10 +27,11 @@ * @author 陈添明 * @since 2022/5/1 8:02 下午 */ -public class Resilience4jRetrofitDegrade extends BaseRetrofitDegrade { +public class Resilience4jRetrofitDegrade extends BaseRetrofitDegrade implements ApplicationContextAware { protected final CircuitBreakerRegistry circuitBreakerRegistry; protected final GlobalResilience4jDegradeProperty globalResilience4jDegradeProperty; + protected ApplicationContext applicationContext; public Resilience4jRetrofitDegrade(CircuitBreakerRegistry circuitBreakerRegistry, GlobalResilience4jDegradeProperty globalResilience4jDegradeProperty) { @@ -62,80 +65,11 @@ public void loadDegradeRules(Class retrofitInterface) { 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(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(maxWaitDurationInHalfOpenStateSeconds)); - } - circuitBreakerRegistry.circuitBreaker(parseResourceName(method), builder.build()); + String circuitBreakerConfigBeanName = + resilience4jDegrade == null ? globalResilience4jDegradeProperty.getCircuitBreakerConfigBeanName() + : resilience4jDegrade.circuitBreakerConfigBeanName(); + circuitBreakerRegistry.circuitBreaker(parseResourceName(method), + applicationContext.getBean(circuitBreakerConfigBeanName, CircuitBreakerConfig.class)); } } @@ -173,4 +107,9 @@ public Response intercept(Chain chain) throws IOException { throw throwable; } } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } } diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/RetrofitTestApplication.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/RetrofitTestApplication.java index 84d3ab1..528cb63 100644 --- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/RetrofitTestApplication.java +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/RetrofitTestApplication.java @@ -4,8 +4,8 @@ import org.springframework.boot.SpringApplication; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Primary; +import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig; import lombok.extern.slf4j.Slf4j; import okhttp3.ConnectionPool; import okhttp3.Dispatcher; @@ -25,18 +25,17 @@ public static void main(String[] args) { } @Bean - GsonConverterFactory gsonConverterFactory() { + public GsonConverterFactory gsonConverterFactory() { return GsonConverterFactory.create(); } @Bean - JaxbConverterFactory jaxbConverterFactory() { + public JaxbConverterFactory jaxbConverterFactory() { return JaxbConverterFactory.create(); } @Bean - @Primary - OkHttpClient defaultBaseOkHttpClient() { + public OkHttpClient defaultBaseOkHttpClient() { return new OkHttpClient.Builder() .addInterceptor(chain -> { log.info("=======替换defaultBaseOkHttpClient构建OkHttpClient====="); @@ -46,7 +45,7 @@ OkHttpClient defaultBaseOkHttpClient() { } @Bean - OkHttpClient testOkHttpClient() { + public OkHttpClient testOkHttpClient() { Dispatcher dispatcher = new Dispatcher(); dispatcher.setMaxRequests(100); dispatcher.setMaxRequestsPerHost(10); @@ -63,4 +62,25 @@ OkHttpClient testOkHttpClient() { }) .build(); } + + @Bean + public CircuitBreakerConfig defaultCircuitBreakerConfig() { + log.info("===替换defaultCircuitBreakerConfig===="); + return CircuitBreakerConfig.ofDefaults(); + } + + @Bean + public CircuitBreakerConfig testCircuitBreakerConfig() { + return CircuitBreakerConfig.custom() + .slidingWindowType(CircuitBreakerConfig.SlidingWindowType.TIME_BASED) + .failureRateThreshold(30) + .minimumNumberOfCalls(10) + .permittedNumberOfCallsInHalfOpenState(5) + .build(); + } + + @Bean + public InvalidRespErrorDecoder invalidRespErrorDecoder() { + return new InvalidRespErrorDecoder(); + } } 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 c7eab1a..c74f5e6 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 @@ -11,7 +11,6 @@ import com.github.lianjiatech.retrofit.spring.boot.test.entity.Person; import com.github.lianjiatech.retrofit.spring.boot.test.entity.Result; -import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig; import retrofit2.http.GET; import retrofit2.http.Query; @@ -20,15 +19,13 @@ */ @Retry(enable = false) @RetrofitClient(baseUrl = "${test.baseUrl}", fallbackFactory = DegradeR4jApi.HttpDegradeFallbackFactory.class) -@Resilience4jDegrade(slidingWindowType = CircuitBreakerConfig.SlidingWindowType.TIME_BASED, - failureRateThreshold = 30, minimumNumberOfCalls = 10, permittedNumberOfCallsInHalfOpenState = 5) +@Resilience4jDegrade(circuitBreakerConfigBeanName = "testCircuitBreakerConfig") public interface DegradeR4jApi { @GET("degrade/person1") Result getPerson1(@Query("id") Long id); - @Resilience4jDegrade(slidingWindowType = CircuitBreakerConfig.SlidingWindowType.TIME_BASED, - failureRateThreshold = 30, minimumNumberOfCalls = 10, permittedNumberOfCallsInHalfOpenState = 5) + @Resilience4jDegrade(circuitBreakerConfigBeanName = "testCircuitBreakerConfig") @GET("degrade/person2") Result getPerson2(@Query("id") Long id); diff --git a/src/test/resources/application-r4j.yml b/src/test/resources/application-r4j.yml index ce0dc09..6400dde 100644 --- a/src/test/resources/application-r4j.yml +++ b/src/test/resources/application-r4j.yml @@ -7,29 +7,5 @@ retrofit: 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 + # 根据该名称从Spring容器中获取CircuitBreakerConfig,作为全局熔断配置 + circuit-breaker-config-bean-name: defaultCircuitBreakerConfig \ No newline at end of file diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index 1afddf7..335fe3c 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -51,32 +51,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 test: baseUrl: http://localhost:8080/api/test/ diff --git a/src/test/resources/default-config.yml b/src/test/resources/default-config.yml index f4e67e7..bd04109 100644 --- a/src/test/resources/default-config.yml +++ b/src/test/resources/default-config.yml @@ -49,29 +49,5 @@ 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