Skip to content

Commit

Permalink
Revert "熔断限流组件优化集成逻辑"
Browse files Browse the repository at this point in the history
  • Loading branch information
chentianming11 authored Apr 17, 2022
1 parent f804b10 commit e3f597a
Show file tree
Hide file tree
Showing 18 changed files with 250 additions and 404 deletions.
9 changes: 0 additions & 9 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
<okio.version>1.17.5</okio.version>
<sentinel.version>1.6.3</sentinel.version>
<jackson.version>2.12.6.1</jackson.version>
<resilience4j-spring.version>1.7.1</resilience4j-spring.version>
</properties>

<dependencies>
Expand Down Expand Up @@ -160,14 +159,6 @@
<version>${sentinel.version}</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.github.resilience4j/resilience4j-spring -->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot2</artifactId>
<version>${resilience4j-spring.version}</version>
<scope>provided</scope>
</dependency>

</dependencies>

<distributionManagement>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,14 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

import com.alibaba.csp.sentinel.SphU;
import com.github.lianjiatech.retrofit.spring.boot.degrade.DegradeRuleRegister;
import com.github.lianjiatech.retrofit.spring.boot.degrade.Resilience4jDegradeRuleRegister;
import com.github.lianjiatech.retrofit.spring.boot.degrade.SentinelDegradeRuleRegister;
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
Expand All @@ -38,6 +29,7 @@
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;
Expand Down Expand Up @@ -79,7 +71,7 @@ public GlobalAndNetworkInterceptorFinder globalAndNetworkInterceptorFinder() {

@Bean
@ConditionalOnMissingBean
public RetrofitConfigBean retrofitConfigBean(ObjectProvider<DegradeRuleRegister> degradeRuleRegisterObjectProvider) throws IllegalAccessException, InstantiationException {
public RetrofitConfigBean retrofitConfigBean() throws IllegalAccessException, InstantiationException {
RetrofitConfigBean retrofitConfigBean =
new RetrofitConfigBean(retrofitProperties, globalAndNetworkInterceptorFinder());
// Initialize the connection pool
Expand Down Expand Up @@ -129,28 +121,9 @@ public RetrofitConfigBean retrofitConfigBean(ObjectProvider<DegradeRuleRegister>
Class<? extends BaseResourceNameParser> resourceNameParser = degrade.getResourceNameParser();
retrofitConfigBean.setResourceNameParser(resourceNameParser.newInstance());

// degrade register
retrofitConfigBean.setDegradeRuleRegister(degradeRuleRegisterObjectProvider.getIfAvailable());

return retrofitConfigBean;
}

@Bean
@ConditionalOnMissingBean
@ConditionalOnClass(SphU.class)
@ConditionalOnProperty(name = "retrofit.degrade.degrade-type", havingValue = "sentinel")
public DegradeRuleRegister sentinelDegradeRuleRegister(){
return new SentinelDegradeRuleRegister();
}

@Bean
@ConditionalOnMissingBean
@ConditionalOnClass(CircuitBreaker.class)
@ConditionalOnProperty(name = "retrofit.degrade.degrade-type", havingValue = "resilience4j")
public DegradeRuleRegister resilience4JDegradeRuleRegister(CircuitBreakerRegistry circuitBreakerRegistry){
return new Resilience4jDegradeRuleRegister(circuitBreakerRegistry);
}


@Bean
@ConditionalOnMissingBean
Expand All @@ -172,6 +145,11 @@ 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import java.util.Map;

import com.github.lianjiatech.retrofit.spring.boot.degrade.BaseResourceNameParser;
import com.github.lianjiatech.retrofit.spring.boot.degrade.DegradeRuleRegister;
import com.github.lianjiatech.retrofit.spring.boot.interceptor.GlobalAndNetworkInterceptorFinder;
import com.github.lianjiatech.retrofit.spring.boot.interceptor.GlobalInterceptor;
import com.github.lianjiatech.retrofit.spring.boot.interceptor.NetworkInterceptor;
Expand Down Expand Up @@ -38,8 +37,6 @@ public class RetrofitConfigBean {

private BaseResourceNameParser resourceNameParser;

private DegradeRuleRegister degradeRuleRegister;

public RetrofitProperties getRetrofitProperties() {
return retrofitProperties;
}
Expand Down Expand Up @@ -108,12 +105,4 @@ public BaseResourceNameParser getResourceNameParser() {
public void setResourceNameParser(BaseResourceNameParser resourceNameParser) {
this.resourceNameParser = resourceNameParser;
}

public DegradeRuleRegister getDegradeRuleRegister() {
return degradeRuleRegister;
}

public void setDegradeRuleRegister(DegradeRuleRegister degradeRuleRegister) {
this.degradeRuleRegister = degradeRuleRegister;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.github.lianjiatech.retrofit.spring.boot.degrade.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
Expand All @@ -33,6 +36,14 @@
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.SentinelDegradeInterceptor;
import com.github.lianjiatech.retrofit.spring.boot.interceptor.BaseLoggingInterceptor;
import com.github.lianjiatech.retrofit.spring.boot.interceptor.BasePathMatchInterceptor;
import com.github.lianjiatech.retrofit.spring.boot.interceptor.ErrorDecoderInterceptor;
Expand Down Expand Up @@ -62,7 +73,7 @@ public class RetrofitFactoryBean<T> implements FactoryBean<T>, EnvironmentAware,
private static final Map<Class<? extends CallAdapter.Factory>, CallAdapter.Factory> CALL_ADAPTER_FACTORIES_CACHE =
new HashMap<>(4);

private final Class<T> retrofitInterface;
private Class<T> retrofitInterface;

private Environment environment;

Expand All @@ -72,7 +83,7 @@ public class RetrofitFactoryBean<T> implements FactoryBean<T>, EnvironmentAware,

private ApplicationContext applicationContext;

private final RetrofitClient retrofitClient;
private RetrofitClient retrofitClient;

private static final Map<Class<? extends Converter.Factory>, Converter.Factory> CONVERTER_FACTORIES_CACHE =
new HashMap<>(4);
Expand Down Expand Up @@ -111,52 +122,40 @@ public T getObject() throws Exception {
);
}

/**
* 加载熔断配置,熔断粒度可控制到方法级别
*/
private void loadDegradeRules() {
DegradeProperty degradeProperty = retrofitProperties.getDegrade();
DegradeRuleRegister degradeRuleRegister = retrofitConfigBean.getDegradeRuleRegister();

if (!degradeProperty.isEnable()) {
return;
}
Assert.notNull(degradeRuleRegister, "[DegradeRuleRegister] not found bean instance");
// 读取熔断配置
Method[] methods = retrofitInterface.getMethods();
List<RetrofitDegradeRule> retrofitDegradeRuleList = Arrays.stream(methods)
.map(this::convertSentinelRule)
.filter(Objects::nonNull)
.collect(Collectors.toList());
degradeRuleRegister.batchRegister(retrofitDegradeRuleList);
}
for (Method method : methods) {
if (method.isDefault()) {
continue;
}
int modifiers = method.getModifiers();
if (Modifier.isStatic(modifiers)) {
continue;
}
// 获取熔断配置
Degrade degrade;
if (method.isAnnotationPresent(Degrade.class)) {
degrade = method.getAnnotation(Degrade.class);
} else {
degrade = retrofitInterface.getAnnotation(Degrade.class);
}

/**
* 提取熔断规则,优先级为方法>类>默认
* @param method method
* @return RetrofitDegradeRule
*/
private RetrofitDegradeRule convertSentinelRule(Method method) {
if (method.isDefault()) {
return null;
}
int modifiers = method.getModifiers();
if (Modifier.isStatic(modifiers)) {
return null;
}
// 获取熔断配置
Degrade degrade;
if (method.isAnnotationPresent(Degrade.class)) {
degrade = method.getAnnotation(Degrade.class);
} else {
degrade = retrofitInterface.getAnnotation(Degrade.class);
if (degrade == null) {
continue;
}

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);
}
BaseResourceNameParser resourceNameParser = retrofitConfigBean.getResourceNameParser();
String resourceName = resourceNameParser.parseResourceName(method, environment);
RetrofitDegradeRule degradeRule = new RetrofitDegradeRule();
degradeRule.setCount(Optional.ofNullable(degrade).map(Degrade::count).orElse(null));
degradeRule.setTimeWindow(Optional.ofNullable(degrade).map(Degrade::timeWindow).orElse(null));
degradeRule.setResourceName(resourceName);
return degradeRule;
}

/**
Expand Down Expand Up @@ -278,14 +277,26 @@ private synchronized OkHttpClient getOkHttpClient(Class<?> retrofitClientInterfa
}

// add DegradeInterceptor
// TODO 这里稍微有点问题,开启熔断则所有实例都会加熔断拦截器,但是拦截器升不生效则取决于是否配置了@Degrade注解,可不可以把这里做成有一个全局默认配置,有@Degrade则走单独配置?
DegradeProperty degradeProperty = retrofitProperties.getDegrade();
if (degradeProperty.isEnable()) {
DegradeInterceptor degradeInterceptor = new DegradeInterceptor();
degradeInterceptor.setEnvironment(environment);
degradeInterceptor.setResourceNameParser(retrofitConfigBean.getResourceNameParser());
degradeInterceptor.setDegradeRuleRegister(retrofitConfigBean.getDegradeRuleRegister());
okHttpClientBuilder.addInterceptor(degradeInterceptor);
DegradeType degradeType = degradeProperty.getDegradeType();
switch (degradeType) {
case SENTINEL: {
try {
Class.forName("com.alibaba.csp.sentinel.SphU");
SentinelDegradeInterceptor sentinelDegradeInterceptor = new SentinelDegradeInterceptor();
sentinelDegradeInterceptor.setEnvironment(environment);
sentinelDegradeInterceptor.setResourceNameParser(retrofitConfigBean.getResourceNameParser());
okHttpClientBuilder.addInterceptor(sentinelDegradeInterceptor);
} catch (ClassNotFoundException e) {
logger.warn("com.alibaba.csp.sentinel not found! No SentinelDegradeInterceptor is set.");
}
break;
}
default: {
throw new IllegalArgumentException("Not currently supported! degradeType=" + degradeType);
}
}
}

// add ServiceInstanceChooserInterceptor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,12 @@
/**
* @author 陈添明
*/
public class DegradeInterceptor implements Interceptor {
public abstract class BaseDegradeInterceptor implements Interceptor {

private Environment environment;

private BaseResourceNameParser resourceNameParser;

protected DegradeRuleRegister degradeRuleRegister;

public void setDegradeRuleRegister(DegradeRuleRegister degradeRuleRegister) {
this.degradeRuleRegister = degradeRuleRegister;
}

public void setEnvironment(Environment environment) {
this.environment = environment;
}
Expand Down Expand Up @@ -53,8 +47,5 @@ public Response intercept(Chain chain) throws IOException {
* @throws IOException IOException
*
*/
protected Response degradeIntercept(String resourceName, Chain chain) throws RetrofitBlockException, IOException {
Request request = chain.request();
return this.degradeRuleRegister.exec(resourceName, () -> chain.proceed(request));
}
protected abstract Response degradeIntercept(String resourceName, Chain chain) throws RetrofitBlockException, IOException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,25 @@
import java.lang.annotation.*;

/**
* 应仅采用异常比例模式来控制熔断,超时导致的报错应在okhttp这一层做
* @author 陈添明 [email protected]
* @author 陈添明
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Documented
public @interface Degrade {

/**
* 异常比例
* RT threshold or exception ratio threshold count.
*/
float count();
double count();

/**
* 时间窗口size,单位:秒
* 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;
}

This file was deleted.

Loading

0 comments on commit e3f597a

Please sign in to comment.