feat: 2.3.0
1. 修复 Bean 'xxx' of type [xxxx] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 问题
This commit is contained in:
parent
2c3be456b6
commit
5a60d5108e
@ -1,13 +1,11 @@
|
||||
package com.aizuda.easy.retry.client.core.intercepter;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.aizuda.easy.retry.client.core.annotation.Retryable;
|
||||
import com.aizuda.easy.retry.client.core.cache.GroupVersionCache;
|
||||
import com.aizuda.easy.retry.client.core.cache.RetryerInfoCache;
|
||||
import com.aizuda.easy.retry.client.core.config.EasyRetryProperties;
|
||||
import com.aizuda.easy.retry.client.core.exception.EasyRetryClientException;
|
||||
import com.aizuda.easy.retry.client.core.intercepter.RetrySiteSnapshot.EnumStage;
|
||||
import com.aizuda.easy.retry.client.core.retryer.RetryerInfo;
|
||||
import com.aizuda.easy.retry.client.core.retryer.RetryerResultContext;
|
||||
@ -15,6 +13,7 @@ import com.aizuda.easy.retry.client.core.strategy.RetryStrategy;
|
||||
import com.aizuda.easy.retry.common.core.alarm.Alarm;
|
||||
import com.aizuda.easy.retry.common.core.alarm.AlarmContext;
|
||||
import com.aizuda.easy.retry.common.core.alarm.EasyRetryAlarmFactory;
|
||||
import com.aizuda.easy.retry.common.core.context.SpringContext;
|
||||
import com.aizuda.easy.retry.common.core.enums.NotifySceneEnum;
|
||||
import com.aizuda.easy.retry.common.core.enums.RetryResultStatusEnum;
|
||||
import com.aizuda.easy.retry.common.core.log.LogUtils;
|
||||
@ -25,14 +24,12 @@ import com.google.common.base.Defaults;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.springframework.aop.AfterAdvice;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
@ -48,7 +45,6 @@ import java.util.UUID;
|
||||
* @date 2023-08-23
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class EasyRetryInterceptor implements MethodInterceptor, AfterAdvice, Serializable, Ordered {
|
||||
|
||||
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
@ -56,22 +52,23 @@ public class EasyRetryInterceptor implements MethodInterceptor, AfterAdvice, Ser
|
||||
"<font face=\"微软雅黑\" color=#ff0000 size=4>{}环境 重试组件异常</font> \r\n" +
|
||||
"> 名称:{} \r\n" +
|
||||
"> 时间:{} \r\n" +
|
||||
"> 异常:{} \n"
|
||||
;
|
||||
"> 异常:{} \n";
|
||||
|
||||
private final StandardEnvironment standardEnvironment;
|
||||
private final RetryStrategy retryStrategy;
|
||||
|
||||
public EasyRetryInterceptor(StandardEnvironment standardEnvironment,
|
||||
RetryStrategy localRetryStrategies) {
|
||||
this.standardEnvironment = standardEnvironment;
|
||||
this.retryStrategy = localRetryStrategies;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
@Qualifier("localRetryStrategies")
|
||||
private RetryStrategy retryStrategy;
|
||||
@Autowired
|
||||
private EasyRetryAlarmFactory easyRetryAlarmFactory;
|
||||
@Autowired
|
||||
private StandardEnvironment standardEnvironment;
|
||||
@Override
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||
|
||||
String traceId = UUID.randomUUID().toString();
|
||||
|
||||
LogUtils.debug(log,"Start entering the around method traceId:[{}]", traceId);
|
||||
LogUtils.debug(log, "Start entering the around method traceId:[{}]", traceId);
|
||||
Retryable retryable = getAnnotationParameter(invocation.getMethod());
|
||||
String executorClassName = invocation.getThis().getClass().getName();
|
||||
String methodEntrance = getMethodEntrance(retryable, executorClassName);
|
||||
@ -88,17 +85,20 @@ public class EasyRetryInterceptor implements MethodInterceptor, AfterAdvice, Ser
|
||||
throwable = t;
|
||||
} finally {
|
||||
|
||||
LogUtils.debug(log,"Start retrying. traceId:[{}] scene:[{}] executorClassName:[{}]", traceId, retryable.scene(), executorClassName);
|
||||
LogUtils.debug(log, "Start retrying. traceId:[{}] scene:[{}] executorClassName:[{}]", traceId,
|
||||
retryable.scene(), executorClassName);
|
||||
// 入口则开始处理重试
|
||||
retryerResultContext = doHandlerRetry(invocation, traceId, retryable, executorClassName, methodEntrance, throwable);
|
||||
retryerResultContext = doHandlerRetry(invocation, traceId, retryable, executorClassName, methodEntrance,
|
||||
throwable);
|
||||
}
|
||||
|
||||
LogUtils.debug(log,"Method return value is [{}]. traceId:[{}]", result, traceId, throwable);
|
||||
LogUtils.debug(log, "Method return value is [{}]. traceId:[{}]", result, traceId, throwable);
|
||||
|
||||
// 若是重试完成了, 则判断是否返回重试完成后的数据
|
||||
if (Objects.nonNull(retryerResultContext)) {
|
||||
// 重试成功直接返回结果 若注解配置了isThrowException=false 则不抛出异常
|
||||
if (retryerResultContext.getRetryResultStatusEnum().getStatus().equals(RetryResultStatusEnum.SUCCESS.getStatus())
|
||||
if (retryerResultContext.getRetryResultStatusEnum().getStatus()
|
||||
.equals(RetryResultStatusEnum.SUCCESS.getStatus())
|
||||
|| !retryable.isThrowException()) {
|
||||
|
||||
// 若返回值是NULL且是基本类型则返回默认值
|
||||
@ -120,7 +120,8 @@ public class EasyRetryInterceptor implements MethodInterceptor, AfterAdvice, Ser
|
||||
}
|
||||
|
||||
|
||||
private RetryerResultContext doHandlerRetry(MethodInvocation invocation, String traceId, Retryable retryable, String executorClassName, String methodEntrance, Throwable throwable) {
|
||||
private RetryerResultContext doHandlerRetry(MethodInvocation invocation, String traceId, Retryable retryable,
|
||||
String executorClassName, String methodEntrance, Throwable throwable) {
|
||||
|
||||
if (!RetrySiteSnapshot.isMethodEntrance(methodEntrance)
|
||||
|| RetrySiteSnapshot.isRunning()
|
||||
@ -133,16 +134,20 @@ public class EasyRetryInterceptor implements MethodInterceptor, AfterAdvice, Ser
|
||||
|| !validate(throwable, RetryerInfoCache.get(retryable.scene(), executorClassName))
|
||||
) {
|
||||
if (!RetrySiteSnapshot.isMethodEntrance(methodEntrance)) {
|
||||
LogUtils.debug(log, "Non-method entry does not enable local retries. traceId:[{}] [{}]", traceId, RetrySiteSnapshot.getMethodEntrance());
|
||||
LogUtils.debug(log, "Non-method entry does not enable local retries. traceId:[{}] [{}]", traceId,
|
||||
RetrySiteSnapshot.getMethodEntrance());
|
||||
} else if (RetrySiteSnapshot.isRunning()) {
|
||||
LogUtils.debug(log, "Existing running retry tasks do not enable local retries. traceId:[{}] [{}]", traceId, EnumStage.valueOfStage(RetrySiteSnapshot.getStage()));
|
||||
LogUtils.debug(log, "Existing running retry tasks do not enable local retries. traceId:[{}] [{}]",
|
||||
traceId, EnumStage.valueOfStage(RetrySiteSnapshot.getStage()));
|
||||
} else if (Objects.isNull(throwable)) {
|
||||
LogUtils.debug(log, "No exception, no local retries. traceId:[{}]", traceId);
|
||||
} else if (RetrySiteSnapshot.isRetryFlow()) {
|
||||
LogUtils.debug(log, "Retry traffic does not enable local retries. traceId:[{}] [{}]", traceId, RetrySiteSnapshot.getRetryHeader());
|
||||
LogUtils.debug(log, "Retry traffic does not enable local retries. traceId:[{}] [{}]", traceId,
|
||||
RetrySiteSnapshot.getRetryHeader());
|
||||
} else if (RetrySiteSnapshot.isRetryForStatusCode()) {
|
||||
LogUtils.debug(log, "Existing exception retry codes do not enable local retries. traceId:[{}]", traceId);
|
||||
} else if(!validate(throwable, RetryerInfoCache.get(retryable.scene(), executorClassName))) {
|
||||
LogUtils.debug(log, "Existing exception retry codes do not enable local retries. traceId:[{}]",
|
||||
traceId);
|
||||
} else if (!validate(throwable, RetryerInfoCache.get(retryable.scene(), executorClassName))) {
|
||||
LogUtils.debug(log, "Exception mismatch. traceId:[{}]", traceId);
|
||||
} else {
|
||||
LogUtils.debug(log, "Unknown situations do not enable local retry scenarios. traceId:[{}]", traceId);
|
||||
@ -153,23 +158,25 @@ public class EasyRetryInterceptor implements MethodInterceptor, AfterAdvice, Ser
|
||||
return openRetry(invocation, traceId, retryable, executorClassName, throwable);
|
||||
}
|
||||
|
||||
private RetryerResultContext openRetry(MethodInvocation point, String traceId, Retryable retryable, String executorClassName, Throwable throwable) {
|
||||
private RetryerResultContext openRetry(MethodInvocation point, String traceId, Retryable retryable,
|
||||
String executorClassName, Throwable throwable) {
|
||||
|
||||
try {
|
||||
|
||||
// 标识重试流量
|
||||
initHeaders(retryable);
|
||||
|
||||
RetryerResultContext context = retryStrategy.openRetry(retryable.scene(), executorClassName, point.getArguments());
|
||||
RetryerResultContext context = retryStrategy.openRetry(retryable.scene(), executorClassName,
|
||||
point.getArguments());
|
||||
if (RetryResultStatusEnum.SUCCESS.getStatus().equals(context.getRetryResultStatusEnum().getStatus())) {
|
||||
LogUtils.debug(log, "local retry successful. traceId:[{}] result:[{}]", traceId, context.getResult());
|
||||
} else {
|
||||
LogUtils.info(log,"local retry result. traceId:[{}] throwable:[{}]", traceId, context.getThrowable());
|
||||
LogUtils.info(log, "local retry result. traceId:[{}] throwable:[{}]", traceId, context.getThrowable());
|
||||
}
|
||||
|
||||
return context;
|
||||
} catch (Exception e) {
|
||||
LogUtils.error(log,"retry component handling exception,traceId:[{}]", traceId, e);
|
||||
LogUtils.error(log, "retry component handling exception,traceId:[{}]", traceId, e);
|
||||
|
||||
// 预警
|
||||
sendMessage(e);
|
||||
@ -193,7 +200,8 @@ public class EasyRetryInterceptor implements MethodInterceptor, AfterAdvice, Ser
|
||||
private void sendMessage(Exception e) {
|
||||
|
||||
try {
|
||||
ConfigDTO.Notify notifyAttribute = GroupVersionCache.getNotifyAttribute(NotifySceneEnum.CLIENT_COMPONENT_ERROR.getNotifyScene());
|
||||
ConfigDTO.Notify notifyAttribute = GroupVersionCache.getNotifyAttribute(
|
||||
NotifySceneEnum.CLIENT_COMPONENT_ERROR.getNotifyScene());
|
||||
if (Objects.nonNull(notifyAttribute)) {
|
||||
AlarmContext context = AlarmContext.build()
|
||||
.text(retryErrorMoreThresholdTextMessageFormatter,
|
||||
@ -204,7 +212,7 @@ public class EasyRetryInterceptor implements MethodInterceptor, AfterAdvice, Ser
|
||||
.title("retry component handling exception:[{}]", EasyRetryProperties.getGroup())
|
||||
.notifyAttribute(notifyAttribute.getNotifyAttribute());
|
||||
|
||||
Alarm<AlarmContext> alarmType = easyRetryAlarmFactory.getAlarmType(notifyAttribute.getNotifyType());
|
||||
Alarm<AlarmContext> alarmType = SpringContext.getBeanByType(EasyRetryAlarmFactory.class).getAlarmType(notifyAttribute.getNotifyType());
|
||||
alarmType.asyncSendMessage(context);
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
@ -246,7 +254,6 @@ public class EasyRetryInterceptor implements MethodInterceptor, AfterAdvice, Ser
|
||||
}
|
||||
|
||||
|
||||
|
||||
private boolean validate(Throwable throwable, RetryerInfo retryerInfo) {
|
||||
|
||||
Set<Class<? extends Throwable>> exclude = retryerInfo.getExclude();
|
||||
|
@ -3,6 +3,7 @@ package com.aizuda.easy.retry.client.core.intercepter;
|
||||
import com.aizuda.easy.retry.client.core.annotation.Retryable;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aopalliance.aop.Advice;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.springframework.aop.ClassFilter;
|
||||
import org.springframework.aop.IntroductionAdvisor;
|
||||
import org.springframework.aop.MethodMatcher;
|
||||
@ -14,8 +15,6 @@ import org.springframework.aop.support.annotation.AnnotationMethodMatcher;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
@ -28,14 +27,17 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
* @author www.byteblogs.com
|
||||
* @date 2023-08-23
|
||||
*/
|
||||
@Configuration
|
||||
//@Configuration
|
||||
@Slf4j
|
||||
public class EasyRetryPointcutAdvisor extends AbstractPointcutAdvisor implements IntroductionAdvisor, BeanFactoryAware, InitializingBean {
|
||||
private Advice advice;
|
||||
private Pointcut pointcut;
|
||||
private BeanFactory beanFactory;
|
||||
@Autowired
|
||||
private EasyRetryInterceptor easyRetryInterceptor;
|
||||
private MethodInterceptor easyRetryInterceptor;
|
||||
|
||||
public EasyRetryPointcutAdvisor(MethodInterceptor methodInterceptor) {
|
||||
this.easyRetryInterceptor = methodInterceptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
|
@ -1,269 +0,0 @@
|
||||
package com.aizuda.easy.retry.client.core.intercepter;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.aizuda.easy.retry.client.core.cache.GroupVersionCache;
|
||||
import com.aizuda.easy.retry.client.core.cache.RetryerInfoCache;
|
||||
import com.aizuda.easy.retry.client.core.config.EasyRetryProperties;
|
||||
import com.aizuda.easy.retry.client.core.exception.EasyRetryClientException;
|
||||
import com.aizuda.easy.retry.client.core.intercepter.RetrySiteSnapshot.EnumStage;
|
||||
import com.aizuda.easy.retry.client.core.retryer.RetryerInfo;
|
||||
import com.aizuda.easy.retry.client.core.strategy.RetryStrategy;
|
||||
import com.aizuda.easy.retry.client.core.annotation.Retryable;
|
||||
import com.aizuda.easy.retry.client.core.retryer.RetryerResultContext;
|
||||
import com.aizuda.easy.retry.common.core.alarm.Alarm;
|
||||
import com.aizuda.easy.retry.common.core.alarm.AlarmContext;
|
||||
import com.aizuda.easy.retry.common.core.alarm.EasyRetryAlarmFactory;
|
||||
import com.aizuda.easy.retry.common.core.enums.NotifySceneEnum;
|
||||
import com.aizuda.easy.retry.common.core.enums.RetryResultStatusEnum;
|
||||
import com.aizuda.easy.retry.common.core.log.LogUtils;
|
||||
import com.aizuda.easy.retry.common.core.model.EasyRetryHeaders;
|
||||
import com.aizuda.easy.retry.common.core.util.EnvironmentUtils;
|
||||
import com.aizuda.easy.retry.server.model.dto.ConfigDTO;
|
||||
import com.google.common.base.Defaults;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author: www.byteblogs.com
|
||||
* @date : 2022-03-03 11:41
|
||||
*/
|
||||
//@Aspect
|
||||
//@Component
|
||||
@Deprecated
|
||||
@Slf4j
|
||||
public class RetryAspect implements Ordered {
|
||||
|
||||
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
private static String retryErrorMoreThresholdTextMessageFormatter =
|
||||
"<font face=\"微软雅黑\" color=#ff0000 size=4>{}环境 重试组件异常</font> \r\n" +
|
||||
"> 名称:{} \r\n" +
|
||||
"> 时间:{} \r\n" +
|
||||
"> 异常:{} \n"
|
||||
;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("localRetryStrategies")
|
||||
private RetryStrategy retryStrategy;
|
||||
@Autowired
|
||||
private EasyRetryAlarmFactory easyRetryAlarmFactory;
|
||||
@Autowired
|
||||
private StandardEnvironment standardEnvironment;
|
||||
|
||||
@Around("@annotation(com.aizuda.easy.retry.client.core.annotation.Retryable)")
|
||||
public Object around(ProceedingJoinPoint point) throws Throwable {
|
||||
String traceId = UUID.randomUUID().toString();
|
||||
|
||||
LogUtils.debug(log,"Start entering the around method traceId:[{}]", traceId);
|
||||
Retryable retryable = getAnnotationParameter(point);
|
||||
String executorClassName = point.getTarget().getClass().getName();
|
||||
String methodEntrance = getMethodEntrance(retryable, executorClassName);
|
||||
if (StrUtil.isBlank(RetrySiteSnapshot.getMethodEntrance())) {
|
||||
RetrySiteSnapshot.setMethodEntrance(methodEntrance);
|
||||
}
|
||||
|
||||
Throwable throwable = null;
|
||||
Object result = null;
|
||||
RetryerResultContext retryerResultContext;
|
||||
try {
|
||||
result = point.proceed();
|
||||
} catch (Throwable t) {
|
||||
throwable = t;
|
||||
} finally {
|
||||
|
||||
LogUtils.debug(log,"Start retrying. traceId:[{}] scene:[{}] executorClassName:[{}]", traceId, retryable.scene(), executorClassName);
|
||||
// 入口则开始处理重试
|
||||
retryerResultContext = doHandlerRetry(point, traceId, retryable, executorClassName, methodEntrance, throwable);
|
||||
}
|
||||
|
||||
LogUtils.debug(log,"Method return value is [{}]. traceId:[{}]", result, traceId, throwable);
|
||||
|
||||
// 若是重试完成了, 则判断是否返回重试完成后的数据
|
||||
if (Objects.nonNull(retryerResultContext)) {
|
||||
// 重试成功直接返回结果 若注解配置了isThrowException=false 则不抛出异常
|
||||
if (retryerResultContext.getRetryResultStatusEnum().getStatus().equals(RetryResultStatusEnum.SUCCESS.getStatus())
|
||||
|| !retryable.isThrowException()) {
|
||||
|
||||
// 若返回值是NULL且是基本类型则返回默认值
|
||||
MethodSignature signature = (MethodSignature) point.getSignature();
|
||||
if (Objects.isNull(retryerResultContext.getResult()) && signature.getReturnType().isPrimitive()) {
|
||||
return Defaults.defaultValue(signature.getReturnType());
|
||||
}
|
||||
|
||||
return retryerResultContext.getResult();
|
||||
}
|
||||
}
|
||||
|
||||
if (throwable != null) {
|
||||
throw throwable;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private RetryerResultContext doHandlerRetry(ProceedingJoinPoint point, String traceId, Retryable retryable, String executorClassName, String methodEntrance, Throwable throwable) {
|
||||
|
||||
if (!RetrySiteSnapshot.isMethodEntrance(methodEntrance)
|
||||
|| RetrySiteSnapshot.isRunning()
|
||||
|| Objects.isNull(throwable)
|
||||
// 重试流量不开启重试
|
||||
|| RetrySiteSnapshot.isRetryFlow()
|
||||
// 下游响应不重试码,不开启重试
|
||||
|| RetrySiteSnapshot.isRetryForStatusCode()
|
||||
// 匹配异常信息
|
||||
|| !validate(throwable, RetryerInfoCache.get(retryable.scene(), executorClassName))
|
||||
) {
|
||||
if (!RetrySiteSnapshot.isMethodEntrance(methodEntrance)) {
|
||||
LogUtils.debug(log, "Non-method entry does not enable local retries. traceId:[{}] [{}]", traceId, RetrySiteSnapshot.getMethodEntrance());
|
||||
} else if (RetrySiteSnapshot.isRunning()) {
|
||||
LogUtils.debug(log, "Existing running retry tasks do not enable local retries. traceId:[{}] [{}]", traceId, EnumStage.valueOfStage(RetrySiteSnapshot.getStage()));
|
||||
} else if (Objects.isNull(throwable)) {
|
||||
LogUtils.debug(log, "No exception, no local retries. traceId:[{}]", traceId);
|
||||
} else if (RetrySiteSnapshot.isRetryFlow()) {
|
||||
LogUtils.debug(log, "Retry traffic does not enable local retries. traceId:[{}] [{}]", traceId, RetrySiteSnapshot.getRetryHeader());
|
||||
} else if (RetrySiteSnapshot.isRetryForStatusCode()) {
|
||||
LogUtils.debug(log, "Existing exception retry codes do not enable local retries. traceId:[{}]", traceId);
|
||||
} else if(!validate(throwable, RetryerInfoCache.get(retryable.scene(), executorClassName))) {
|
||||
LogUtils.debug(log, "Exception mismatch. traceId:[{}]", traceId);
|
||||
} else {
|
||||
LogUtils.debug(log, "Unknown situations do not enable local retry scenarios. traceId:[{}]", traceId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return openRetry(point, traceId, retryable, executorClassName, throwable);
|
||||
}
|
||||
|
||||
private RetryerResultContext openRetry(ProceedingJoinPoint point, String traceId, Retryable retryable, String executorClassName, Throwable throwable) {
|
||||
|
||||
try {
|
||||
|
||||
// 标识重试流量
|
||||
initHeaders(retryable);
|
||||
|
||||
RetryerResultContext context = retryStrategy.openRetry(retryable.scene(), executorClassName, point.getArgs());
|
||||
LogUtils.info(log,"local retry result. traceId:[{}] message:[{}]", traceId, context);
|
||||
if (RetryResultStatusEnum.SUCCESS.getStatus().equals(context.getRetryResultStatusEnum().getStatus())) {
|
||||
LogUtils.debug(log, "local retry successful. traceId:[{}] result:[{}]", traceId, context.getResult());
|
||||
}
|
||||
|
||||
return context;
|
||||
} catch (Exception e) {
|
||||
LogUtils.error(log,"retry component handling exception,traceId:[{}]", traceId, e);
|
||||
|
||||
// 预警
|
||||
sendMessage(e);
|
||||
|
||||
} finally {
|
||||
RetrySiteSnapshot.removeAll();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void initHeaders(final Retryable retryable) {
|
||||
|
||||
EasyRetryHeaders easyRetryHeaders = new EasyRetryHeaders();
|
||||
easyRetryHeaders.setEasyRetry(Boolean.TRUE);
|
||||
easyRetryHeaders.setEasyRetryId(IdUtil.getSnowflakeNextIdStr());
|
||||
easyRetryHeaders.setDdl(GroupVersionCache.getDdl(retryable.scene()));
|
||||
RetrySiteSnapshot.setRetryHeader(easyRetryHeaders);
|
||||
}
|
||||
|
||||
private void sendMessage(Exception e) {
|
||||
|
||||
try {
|
||||
ConfigDTO.Notify notifyAttribute = GroupVersionCache.getNotifyAttribute(NotifySceneEnum.CLIENT_COMPONENT_ERROR.getNotifyScene());
|
||||
if (Objects.nonNull(notifyAttribute)) {
|
||||
AlarmContext context = AlarmContext.build()
|
||||
.text(retryErrorMoreThresholdTextMessageFormatter,
|
||||
EnvironmentUtils.getActiveProfile(),
|
||||
EasyRetryProperties.getGroup(),
|
||||
LocalDateTime.now().format(formatter),
|
||||
e.getMessage())
|
||||
.title("retry component handling exception:[{}]", EasyRetryProperties.getGroup())
|
||||
.notifyAttribute(notifyAttribute.getNotifyAttribute());
|
||||
|
||||
Alarm<AlarmContext> alarmType = easyRetryAlarmFactory.getAlarmType(notifyAttribute.getNotifyType());
|
||||
alarmType.asyncSendMessage(context);
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
LogUtils.error(log, "Client failed to send component exception alert.", e1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String getMethodEntrance(Retryable retryable, String executorClassName) {
|
||||
|
||||
if (Objects.isNull(retryable)) {
|
||||
return StrUtil.EMPTY;
|
||||
}
|
||||
|
||||
return retryable.scene().concat("_").concat(executorClassName);
|
||||
}
|
||||
|
||||
private Retryable getAnnotationParameter(ProceedingJoinPoint point) {
|
||||
String methodName = point.getSignature().getName();
|
||||
Class<?> classTarget = point.getTarget().getClass();
|
||||
Class<?>[] par = ((MethodSignature) point.getSignature()).getParameterTypes();
|
||||
Method objMethod = null;
|
||||
try {
|
||||
objMethod = classTarget.getMethod(methodName, par);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new EasyRetryClientException("注解配置异常:[{}}", methodName);
|
||||
}
|
||||
return objMethod.getAnnotation(Retryable.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
String order = standardEnvironment
|
||||
.getProperty("easy-retry.aop.order", String.valueOf(Ordered.HIGHEST_PRECEDENCE));
|
||||
return Integer.parseInt(order);
|
||||
}
|
||||
|
||||
private boolean validate(Throwable throwable, RetryerInfo retryerInfo) {
|
||||
|
||||
Set<Class<? extends Throwable>> exclude = retryerInfo.getExclude();
|
||||
Set<Class<? extends Throwable>> include = retryerInfo.getInclude();
|
||||
|
||||
if (CollectionUtils.isEmpty(include) && CollectionUtils.isEmpty(exclude)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (Class<? extends Throwable> e : include) {
|
||||
if (e.isAssignableFrom(throwable.getClass())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!CollectionUtils.isEmpty(exclude)) {
|
||||
for (Class<? extends Throwable> e : exclude) {
|
||||
if (e.isAssignableFrom(throwable.getClass())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,12 +1,36 @@
|
||||
package com.aizuda.easy.retry.client.starter;
|
||||
|
||||
import com.aizuda.easy.retry.client.core.intercepter.EasyRetryInterceptor;
|
||||
import com.aizuda.easy.retry.client.core.intercepter.EasyRetryPointcutAdvisor;
|
||||
import com.aizuda.easy.retry.client.core.strategy.RetryStrategy;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.springframework.aop.Advisor;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.context.annotation.Role;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
|
||||
@Configuration
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
@ComponentScan("com.aizuda.easy.retry.client.core")
|
||||
@ConditionalOnProperty(prefix = "easy-retry", name = "enabled", havingValue = "true")
|
||||
public class EasyRetryClientAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public Advisor easyRetryPointcutAdvisor (MethodInterceptor easyRetryInterceptor) {
|
||||
return new EasyRetryPointcutAdvisor(easyRetryInterceptor);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public MethodInterceptor easyRetryInterceptor(StandardEnvironment standardEnvironment,
|
||||
@Lazy RetryStrategy localRetryStrategies) {
|
||||
return new EasyRetryInterceptor(standardEnvironment, localRetryStrategies);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user