diff --git a/README.md b/README.md
index d6c1b2c..0799978 100644
--- a/README.md
+++ b/README.md
@@ -52,7 +52,7 @@ gitee项目地址:[https://gitee.com/lianjiatech/retrofit-spring-boot-starter]
com.github.lianjiatech
retrofit-spring-boot-starter
- 2.2.22
+ 2.3.0
```
@@ -67,7 +67,7 @@ gitee项目地址:[https://gitee.com/lianjiatech/retrofit-spring-boot-starter]
com.github.lianjiatech
retrofit-spring-boot-starter
- 2.2.22
+ 2.3.0
com.squareup.okhttp3
diff --git a/README_EN.md b/README_EN.md
index bfa0233..a455dbd 100644
--- a/README_EN.md
+++ b/README_EN.md
@@ -43,7 +43,7 @@
com.github.lianjiatech
retrofit-spring-boot-starter
- 2.2.22
+ 2.3.0
```
@@ -53,7 +53,7 @@ This project depends on Retrofit-2.9.0, okhttp-3.14.9, and okio-1.17.5 versions.
com.github.lianjiatech
retrofit-spring-boot-starter
- 2.2.22
+ 2.3.0
com.squareup.okhttp3
diff --git a/pom.xml b/pom.xml
index 84224ba..398728b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.github.lianjiatech
retrofit-spring-boot-starter
- 2.2.22
+ 2.3.0
retrofit-spring-boot-starter
retrofit-spring-boot-starter
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 34c3824..652e5e6 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
@@ -29,7 +29,6 @@
import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitFactoryBean;
import com.github.lianjiatech.retrofit.spring.boot.core.ServiceInstanceChooser;
import com.github.lianjiatech.retrofit.spring.boot.degrade.BaseResourceNameParser;
-import com.github.lianjiatech.retrofit.spring.boot.degrade.RetrofitDegradeRuleInitializer;
import com.github.lianjiatech.retrofit.spring.boot.interceptor.GlobalAndNetworkInterceptorFinder;
import com.github.lianjiatech.retrofit.spring.boot.interceptor.ServiceInstanceChooserInterceptor;
import com.github.lianjiatech.retrofit.spring.boot.retry.BaseRetryInterceptor;
@@ -145,11 +144,6 @@ public void setApplicationContext(ApplicationContext applicationContext) throws
this.applicationContext = applicationContext;
}
- @Bean
- public RetrofitDegradeRuleInitializer retrofitDegradeRuleInitializer() {
- return new RetrofitDegradeRuleInitializer(retrofitProperties.getDegrade());
- }
-
@Configuration
@Import({AutoConfiguredRetrofitScannerRegistrar.class})
@ConditionalOnMissingBean(RetrofitFactoryBean.class)
diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitFactoryBean.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitFactoryBean.java
index f97c8de..f422304 100644
--- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitFactoryBean.java
+++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitFactoryBean.java
@@ -27,6 +27,8 @@
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
+import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
+import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.github.lianjiatech.retrofit.spring.boot.annotation.Intercept;
import com.github.lianjiatech.retrofit.spring.boot.annotation.InterceptMark;
import com.github.lianjiatech.retrofit.spring.boot.annotation.Intercepts;
@@ -36,13 +38,9 @@
import com.github.lianjiatech.retrofit.spring.boot.config.LogProperty;
import com.github.lianjiatech.retrofit.spring.boot.config.RetrofitConfigBean;
import com.github.lianjiatech.retrofit.spring.boot.config.RetrofitProperties;
-import com.github.lianjiatech.retrofit.spring.boot.degrade.BaseResourceNameParser;
-import com.github.lianjiatech.retrofit.spring.boot.degrade.Degrade;
-import com.github.lianjiatech.retrofit.spring.boot.degrade.DegradeStrategy;
import com.github.lianjiatech.retrofit.spring.boot.degrade.DegradeType;
import com.github.lianjiatech.retrofit.spring.boot.degrade.FallbackFactory;
-import com.github.lianjiatech.retrofit.spring.boot.degrade.RetrofitDegradeRule;
-import com.github.lianjiatech.retrofit.spring.boot.degrade.RetrofitDegradeRuleInitializer;
+import com.github.lianjiatech.retrofit.spring.boot.degrade.SentinelDegrade;
import com.github.lianjiatech.retrofit.spring.boot.degrade.SentinelDegradeInterceptor;
import com.github.lianjiatech.retrofit.spring.boot.interceptor.BaseLoggingInterceptor;
import com.github.lianjiatech.retrofit.spring.boot.interceptor.BasePathMatchInterceptor;
@@ -123,8 +121,19 @@ public T getObject() throws Exception {
}
private void loadDegradeRules() {
+ DegradeProperty degrade = retrofitProperties.getDegrade();
+ if (!degrade.isEnable()) {
+ return;
+ }
+ if (degrade.getDegradeType() == DegradeType.SENTINEL) {
+ loadSentinelDegradeRules();
+ }
+ }
+
+ private void loadSentinelDegradeRules() {
// 读取熔断配置
Method[] methods = retrofitInterface.getMethods();
+ List rules = new ArrayList<>();
for (Method method : methods) {
if (method.isDefault()) {
continue;
@@ -134,28 +143,29 @@ private void loadDegradeRules() {
continue;
}
// 获取熔断配置
- Degrade degrade;
- if (method.isAnnotationPresent(Degrade.class)) {
- degrade = method.getAnnotation(Degrade.class);
- } else {
- degrade = retrofitInterface.getAnnotation(Degrade.class);
- }
-
- if (degrade == null) {
+ SentinelDegrade sentinelDegrade = getSentinelDegrade(method);
+ if (sentinelDegrade == null) {
continue;
}
+ String resourceName = retrofitConfigBean.getResourceNameParser().parseResourceName(method, environment);
+ DegradeRule degradeRule = new DegradeRule()
+ .setCount(sentinelDegrade.count())
+ .setTimeWindow(sentinelDegrade.timeWindow())
+ .setGrade(sentinelDegrade.grade());
+ degradeRule.setResource(resourceName);
+ rules.add(degradeRule);
+ }
+ DegradeRuleManager.loadRules(rules);
+ }
- DegradeStrategy degradeStrategy = degrade.degradeStrategy();
- BaseResourceNameParser resourceNameParser = retrofitConfigBean.getResourceNameParser();
- String resourceName = resourceNameParser.parseResourceName(method, environment);
-
- RetrofitDegradeRule degradeRule = new RetrofitDegradeRule();
- degradeRule.setCount(degrade.count());
- degradeRule.setDegradeStrategy(degradeStrategy);
- degradeRule.setTimeWindow(degrade.timeWindow());
- degradeRule.setResourceName(resourceName);
- RetrofitDegradeRuleInitializer.addRetrofitDegradeRule(degradeRule);
+ private SentinelDegrade getSentinelDegrade(Method method) {
+ SentinelDegrade sentinelDegrade;
+ if (method.isAnnotationPresent(SentinelDegrade.class)) {
+ sentinelDegrade = method.getAnnotation(SentinelDegrade.class);
+ } else {
+ sentinelDegrade = retrofitInterface.getAnnotation(SentinelDegrade.class);
}
+ return sentinelDegrade;
}
/**
diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/Degrade.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/Degrade.java
deleted file mode 100644
index febad15..0000000
--- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/Degrade.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.github.lianjiatech.retrofit.spring.boot.degrade;
-
-import java.lang.annotation.*;
-
-/**
- * @author 陈添明
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.METHOD, ElementType.TYPE})
-@Documented
-public @interface Degrade {
-
- /**
- * RT threshold or exception ratio threshold count.
- */
- double count();
-
- /**
- * Degrade recover timeout (in seconds) when degradation occurs.
- */
- int timeWindow() default 5;
-
- /**
- * Degrade strategy (0: average RT, 1: exception ratio).
- */
- DegradeStrategy degradeStrategy() default DegradeStrategy.AVERAGE_RT;
-}
diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/DegradeStrategy.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/DegradeStrategy.java
deleted file mode 100644
index d33ed4c..0000000
--- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/DegradeStrategy.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.github.lianjiatech.retrofit.spring.boot.degrade;
-
-/**
- * @author 陈添明
- */
-public enum DegradeStrategy {
-
- /**
- * average RT
- */
- AVERAGE_RT,
-
- /**
- * exception ratio
- */
- EXCEPTION_RATIO,
-}
diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/RetrofitDegradeRule.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/RetrofitDegradeRule.java
deleted file mode 100644
index 757a4d4..0000000
--- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/RetrofitDegradeRule.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.github.lianjiatech.retrofit.spring.boot.degrade;
-
-/**
- * @author 陈添明
- */
-public class RetrofitDegradeRule {
-
- private String resourceName;
-
- private double count;
-
- private int timeWindow;
-
- private DegradeStrategy degradeStrategy;
-
- public String getResourceName() {
- return resourceName;
- }
-
- public void setResourceName(String resourceName) {
- this.resourceName = resourceName;
- }
-
- public double getCount() {
- return count;
- }
-
- public void setCount(double count) {
- this.count = count;
- }
-
- public int getTimeWindow() {
- return timeWindow;
- }
-
- public void setTimeWindow(int timeWindow) {
- this.timeWindow = timeWindow;
- }
-
- public DegradeStrategy getDegradeStrategy() {
- return degradeStrategy;
- }
-
- public void setDegradeStrategy(DegradeStrategy degradeStrategy) {
- this.degradeStrategy = degradeStrategy;
- }
-}
diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/RetrofitDegradeRuleInitializer.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/RetrofitDegradeRuleInitializer.java
deleted file mode 100644
index 84a5798..0000000
--- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/RetrofitDegradeRuleInitializer.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package com.github.lianjiatech.retrofit.spring.boot.degrade;
-
-import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
-import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
-import com.github.lianjiatech.retrofit.spring.boot.config.DegradeProperty;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.boot.context.event.ApplicationReadyEvent;
-import org.springframework.context.ApplicationListener;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-/**
- * @author 陈添明
- */
-public class RetrofitDegradeRuleInitializer implements ApplicationListener {
-
- private final static Logger logger = LoggerFactory.getLogger(RetrofitDegradeRuleInitializer.class);
-
- private final DegradeProperty degradeProperty;
-
-
- private static List LIST = new CopyOnWriteArrayList<>();
-
- public RetrofitDegradeRuleInitializer(DegradeProperty degradeProperty) {
- this.degradeProperty = degradeProperty;
- }
-
-
- public static void addRetrofitDegradeRule(RetrofitDegradeRule degradeRule) {
- if (degradeRule == null) {
- return;
- }
- LIST.add(degradeRule);
- }
-
-
- /**
- * Handle an application event.
- *
- * @param event the event to respond to
- */
- @Override
- public void onApplicationEvent(ApplicationReadyEvent event) {
- if (!degradeProperty.isEnable()) {
- return;
- }
-
- DegradeType degradeType = degradeProperty.getDegradeType();
- switch (degradeType) {
- case SENTINEL: {
- try {
- Class.forName("com.alibaba.csp.sentinel.SphU");
- List rules = new ArrayList<>();
-
- for (RetrofitDegradeRule degradeRule : LIST) {
- DegradeStrategy degradeStrategy = degradeRule.getDegradeStrategy();
- int grade;
- switch (degradeStrategy) {
- case AVERAGE_RT: {
- grade = 0;
- break;
- }
- case EXCEPTION_RATIO: {
- grade = 1;
- break;
- }
- default: {
- throw new IllegalArgumentException("Not currently supported! degradeStrategy=" + degradeStrategy);
- }
- }
- String resourceName = degradeRule.getResourceName();
- // add degrade rule
- DegradeRule rule = new DegradeRule()
- .setGrade(grade)
- // Max allowed response time
- .setCount(degradeRule.getCount())
- // Retry timeout (in second)
- .setTimeWindow(degradeRule.getTimeWindow());
- rule.setResource(resourceName);
- rules.add(rule);
- }
- DegradeRuleManager.loadRules(rules);
-
- } catch (Exception e) {
- logger.warn("com.alibaba.csp.sentinel not found! No SentinelDegradeInterceptor is set.");
- }
- break;
- }
- default: {
- throw new IllegalArgumentException("Not currently supported! degradeType=" + degradeType);
- }
-
- }
- }
-}
diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/SentinelDegrade.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/SentinelDegrade.java
new file mode 100644
index 0000000..7e87f15
--- /dev/null
+++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/SentinelDegrade.java
@@ -0,0 +1,31 @@
+package com.github.lianjiatech.retrofit.spring.boot.degrade;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @author 陈添明
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Documented
+public @interface SentinelDegrade {
+
+ /**
+ * RT模式下为慢调用临界 RT(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值
+ */
+ double count();
+
+ /**
+ * 熔断时长,单位为 s
+ */
+ int timeWindow() default 5;
+
+ /**
+ * 降级策略(0:平均响应时间;1:异常比例;2:异常数量)
+ */
+ int grade() default 0;
+}
diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/DegradeTest.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/DegradeTest.java
new file mode 100644
index 0000000..cdb1b0b
--- /dev/null
+++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/DegradeTest.java
@@ -0,0 +1,85 @@
+package com.github.lianjiatech.retrofit.spring.boot.test;
+
+import java.io.IOException;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.IntStream;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.lianjiatech.retrofit.spring.boot.test.entity.Person;
+import com.github.lianjiatech.retrofit.spring.boot.test.entity.Result;
+import com.github.lianjiatech.retrofit.spring.boot.test.http.DegradeApi;
+
+import okhttp3.mockwebserver.MockResponse;
+import okhttp3.mockwebserver.MockWebServer;
+
+/**
+ * @author 陈添明
+ * @summary
+ * @since 2022/1/21 4:20 下午
+ */
+@SpringBootTest(classes = RetrofitTestApplication.class)
+@RunWith(SpringRunner.class)
+public class DegradeTest {
+
+ @Autowired
+ private DegradeApi degradeApi;
+
+ private static final ObjectMapper objectMapper =
+ new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
+ .setSerializationInclusion(JsonInclude.Include.NON_NULL);
+
+ private MockWebServer server;
+
+ @Before
+ public void before() throws IOException {
+ System.out.println("=========开启MockWebServer===========");
+ server = new MockWebServer();
+ server.start(8080);
+
+ }
+
+ @After
+ public void after() throws IOException {
+ System.out.println("=========关闭MockWebServer===========");
+ server.close();
+ }
+
+ @Test
+ public void test() throws IOException {
+ Random random = new Random(System.currentTimeMillis());
+ IntStream.range(0, 1000).parallel().forEach((i) -> {
+ try {
+ Person mockPerson = new Person().setId(1L)
+ .setName("test")
+ .setAge(10);
+ Result mockResult = new Result<>()
+ .setCode(0)
+ .setMsg("ok")
+ .setData(mockPerson);
+ MockResponse response = new MockResponse()
+ .setResponseCode(200)
+ .addHeader("Content-Type", "application/text; charset=utf-8")
+ .addHeader("Cache-Control", "no-cache")
+ .setBody(objectMapper.writeValueAsString(mockResult))
+ .setHeadersDelay(random.nextInt(1000), TimeUnit.MILLISECONDS);
+ server.enqueue(response);
+ System.out.println(degradeApi.getPerson(2L).getCode());
+ } catch (Exception e) {
+ System.out.println("抛出异常:" + e.getMessage());
+ } finally {
+ System.out.println("当前请求轮次: " + (i + 1));
+ }
+ });
+ }
+}
diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/DegradeApi.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/DegradeApi.java
new file mode 100644
index 0000000..5f8a6f7
--- /dev/null
+++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/DegradeApi.java
@@ -0,0 +1,30 @@
+package com.github.lianjiatech.retrofit.spring.boot.test.http;
+
+import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient;
+import com.github.lianjiatech.retrofit.spring.boot.degrade.SentinelDegrade;
+import com.github.lianjiatech.retrofit.spring.boot.test.entity.Person;
+import com.github.lianjiatech.retrofit.spring.boot.test.entity.Result;
+
+import retrofit2.http.GET;
+import retrofit2.http.Query;
+
+/**
+ * @author 陈添明
+ * @summary
+ * @since 2022/1/21 4:19 下午
+ */
+@RetrofitClient(baseUrl = "${test.baseUrl}")
+@SentinelDegrade(count = 100)
+public interface DegradeApi {
+
+ /**
+ * 其他任意Java类型
+ * 将响应体内容适配成一个对应的Java类型对象返回,如果http状态码不是2xx,直接抛错!
+ *
+ * @param id id
+ * @return 其他任意Java类型
+ */
+ @GET("person")
+ Result getPerson(@Query("id") Long id);
+
+}