feat: 1.3.0
1. 重构上报模块 2. 使用策略模式,通过异步、同步执行不同的策略方法
This commit is contained in:
parent
ff42df5229
commit
ddfe1a2ce2
@ -0,0 +1,95 @@
|
|||||||
|
package com.aizuda.easy.retry.client.core.report;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import com.aizuda.easy.retry.client.core.IdempotentIdGenerate;
|
||||||
|
import com.aizuda.easy.retry.client.core.RetryArgSerializer;
|
||||||
|
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;
|
||||||
|
import com.aizuda.easy.retry.client.core.retryer.RetryerInfo;
|
||||||
|
import com.aizuda.easy.retry.client.core.spel.SPELParamFunction;
|
||||||
|
import com.aizuda.easy.retry.client.core.window.RetryLeapArray;
|
||||||
|
import com.aizuda.easy.retry.common.core.log.LogUtils;
|
||||||
|
import com.aizuda.easy.retry.server.model.dto.RetryTaskDTO;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author www.byteblogs.com
|
||||||
|
* @date 2023-05-15
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public abstract class AbstractReport implements Report {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier("easyRetryJacksonSerializer")
|
||||||
|
private RetryArgSerializer retryArgSerializer;
|
||||||
|
|
||||||
|
public static final int SAMPLE_COUNT = 10;
|
||||||
|
|
||||||
|
public static final int INTERVAL_IN_MS = 1000;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean report(String scene, final String targetClassName, final Object[] params) {
|
||||||
|
RetryerInfo retryerInfo = RetryerInfoCache.get(scene, targetClassName);
|
||||||
|
Assert.notNull(retryerInfo, () -> new EasyRetryClientException("retryerInfo is null"));
|
||||||
|
|
||||||
|
if (RetrySiteSnapshot.getStage().equals(RetrySiteSnapshot.EnumStage.REMOTE.getStage()) && !retryerInfo.isForceReport()) {
|
||||||
|
LogUtils.info(log, "已经上报成功,无需重复上报 scene:[{}] targetClassName:[{}] args:[{}]",
|
||||||
|
retryerInfo.getScene(), retryerInfo.getExecutorClassName(), params);
|
||||||
|
return Boolean.TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return doReport(retryerInfo, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract boolean doReport(RetryerInfo retryerInfo, Object[] params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建上报任务对象
|
||||||
|
*
|
||||||
|
* @param scene 场景
|
||||||
|
* @param targetClassName 执行对象
|
||||||
|
* @param args 参数
|
||||||
|
* @return RetryTaskDTO 上报服务端对象
|
||||||
|
*/
|
||||||
|
protected RetryTaskDTO buildRetryTaskDTO(final String scene, final String targetClassName, final Object[] args) {
|
||||||
|
RetryerInfo retryerInfo = RetryerInfoCache.get(scene, targetClassName);
|
||||||
|
Method executorMethod = retryerInfo.getMethod();
|
||||||
|
|
||||||
|
RetryTaskDTO retryTaskDTO = new RetryTaskDTO();
|
||||||
|
String idempotentId;
|
||||||
|
try {
|
||||||
|
Class<? extends IdempotentIdGenerate> idempotentIdGenerate = retryerInfo.getIdempotentIdGenerate();
|
||||||
|
IdempotentIdGenerate generate = idempotentIdGenerate.newInstance();
|
||||||
|
Method method = idempotentIdGenerate.getMethod("idGenerate", Object[].class);
|
||||||
|
Object p = new Object[]{scene, targetClassName, args, executorMethod.getName()};
|
||||||
|
idempotentId = (String) ReflectionUtils.invokeMethod(method, generate, p);
|
||||||
|
} catch (Exception exception) {
|
||||||
|
LogUtils.error(log, "幂等id生成异常:{},{}", scene, args, exception);
|
||||||
|
throw new EasyRetryClientException("idempotentId生成异常:{},{}", scene, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
String serialize = retryArgSerializer.serialize(args);
|
||||||
|
retryTaskDTO.setIdempotentId(idempotentId);
|
||||||
|
retryTaskDTO.setExecutorName(targetClassName);
|
||||||
|
retryTaskDTO.setArgsStr(serialize);
|
||||||
|
retryTaskDTO.setGroupName(EasyRetryProperties.getGroup());
|
||||||
|
retryTaskDTO.setSceneName(scene);
|
||||||
|
|
||||||
|
String bizNoSpel = retryerInfo.getBizNo();
|
||||||
|
Function<Object[], String> spelParamFunction = new SPELParamFunction(bizNoSpel, executorMethod);
|
||||||
|
retryTaskDTO.setBizNo(spelParamFunction.apply(args));
|
||||||
|
return retryTaskDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
package com.aizuda.easy.retry.client.core.report;
|
||||||
|
|
||||||
|
import com.aizuda.easy.retry.client.core.Lifecycle;
|
||||||
|
import com.aizuda.easy.retry.client.core.client.NettyClient;
|
||||||
|
import com.aizuda.easy.retry.client.core.client.proxy.RequestBuilder;
|
||||||
|
import com.aizuda.easy.retry.client.core.retryer.RetryerInfo;
|
||||||
|
import com.aizuda.easy.retry.client.core.window.RetryLeapArray;
|
||||||
|
import com.aizuda.easy.retry.common.core.log.LogUtils;
|
||||||
|
import com.aizuda.easy.retry.common.core.model.NettyResult;
|
||||||
|
import com.aizuda.easy.retry.common.core.util.JsonUtil;
|
||||||
|
import com.aizuda.easy.retry.server.model.dto.RetryTaskDTO;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author www.byteblogs.com
|
||||||
|
* @date 2023-05-15
|
||||||
|
* @since 1.3.0
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class AsyncReport extends AbstractReport implements Lifecycle {
|
||||||
|
|
||||||
|
private static ScheduledExecutorService dispatchService = Executors.newSingleThreadScheduledExecutor(r -> new Thread(r, "DispatchService"));
|
||||||
|
|
||||||
|
public static RetryLeapArray slidingWindow = new RetryLeapArray(SAMPLE_COUNT, INTERVAL_IN_MS, new ReportListener());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supports(boolean async) {
|
||||||
|
return async;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean doReport(RetryerInfo retryerInfo, Object[] params) {
|
||||||
|
|
||||||
|
return syncReport(retryerInfo.getScene(), retryerInfo.getExecutorClassName(), params, retryerInfo.getTimeout(), retryerInfo.getUnit());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步上报到服务端, 若当前处于远程重试阶段不会进行执行上报
|
||||||
|
*/
|
||||||
|
public Boolean syncReport(String scene, String targetClassName, Object[] args, long timeout, TimeUnit unit) {
|
||||||
|
|
||||||
|
RetryTaskDTO retryTaskDTO = buildRetryTaskDTO(scene, targetClassName, args);
|
||||||
|
slidingWindow.currentWindow().value().add(retryTaskDTO);
|
||||||
|
|
||||||
|
return Boolean.TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
dispatchService.scheduleAtFixedRate(() -> {
|
||||||
|
slidingWindow.currentWindow();
|
||||||
|
}, INTERVAL_IN_MS, INTERVAL_IN_MS / SAMPLE_COUNT, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
log.info("reportHandler about to shutdown");
|
||||||
|
slidingWindow.currentWindow();
|
||||||
|
log.info("reportHandler has been shutdown");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.aizuda.easy.retry.client.core.report;
|
||||||
|
|
||||||
|
import com.aizuda.easy.retry.client.core.retryer.RetryerInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author www.byteblogs.com
|
||||||
|
* @date 2023-05-15
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public interface Report {
|
||||||
|
|
||||||
|
boolean supports(boolean async);
|
||||||
|
|
||||||
|
boolean report(String scene, final String targetClassName, final Object[] args);
|
||||||
|
}
|
@ -1,169 +0,0 @@
|
|||||||
package com.aizuda.easy.retry.client.core.report;
|
|
||||||
|
|
||||||
import com.aizuda.easy.retry.client.core.IdempotentIdGenerate;
|
|
||||||
import com.aizuda.easy.retry.client.core.RetryArgSerializer;
|
|
||||||
import com.aizuda.easy.retry.client.core.client.NettyClient;
|
|
||||||
import com.aizuda.easy.retry.client.core.client.proxy.RequestBuilder;
|
|
||||||
import com.aizuda.easy.retry.client.core.config.EasyRetryProperties;
|
|
||||||
import com.aizuda.easy.retry.client.core.Lifecycle;
|
|
||||||
import com.aizuda.easy.retry.client.core.cache.RetryerInfoCache;
|
|
||||||
import com.aizuda.easy.retry.client.core.exception.EasyRetryClientException;
|
|
||||||
import com.aizuda.easy.retry.client.core.intercepter.RetrySiteSnapshot;
|
|
||||||
import com.aizuda.easy.retry.client.core.retryer.RetryerInfo;
|
|
||||||
import com.aizuda.easy.retry.client.core.spel.SPELParamFunction;
|
|
||||||
import com.aizuda.easy.retry.client.core.window.RetryLeapArray;
|
|
||||||
import com.aizuda.easy.retry.common.core.log.LogUtils;
|
|
||||||
import com.aizuda.easy.retry.common.core.model.NettyResult;
|
|
||||||
import com.aizuda.easy.retry.common.core.model.Result;
|
|
||||||
import com.aizuda.easy.retry.common.core.util.JsonUtil;
|
|
||||||
import com.aizuda.easy.retry.server.model.dto.RetryTaskDTO;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.util.ReflectionUtils;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 上报服务端
|
|
||||||
*
|
|
||||||
* @author: www.byteblogs.com
|
|
||||||
* @date : 2022-03-08 09:24
|
|
||||||
* @since 1.0.0
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
@Slf4j
|
|
||||||
public class ReportHandler implements Lifecycle {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
@Qualifier("XRetryJacksonSerializer")
|
|
||||||
private RetryArgSerializer retryArgSerializer;
|
|
||||||
|
|
||||||
public static final int SAMPLE_COUNT = 10;
|
|
||||||
|
|
||||||
public static final int INTERVAL_IN_MS = 1000;
|
|
||||||
|
|
||||||
private static ScheduledExecutorService dispatchService = Executors.newSingleThreadScheduledExecutor(r -> new Thread(r, "DispatchService"));
|
|
||||||
|
|
||||||
public static RetryLeapArray slidingWindow = new RetryLeapArray(SAMPLE_COUNT, INTERVAL_IN_MS, new ReportListener());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 异步上报到服务端, 若当前处于远程重试阶段不会进行执行上报
|
|
||||||
*/
|
|
||||||
public Boolean syncReport(String scene, String targetClassName, Object[] args, long timeout, TimeUnit unit) {
|
|
||||||
|
|
||||||
if (RetrySiteSnapshot.getStage().equals(RetrySiteSnapshot.EnumStage.REMOTE.getStage())) {
|
|
||||||
LogUtils.info(log,"已经上报成功,无需重复上报 scene:[{}] targetClassName:[{}] args:[{}]", scene, targetClassName, args);
|
|
||||||
return Boolean.TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return syncReportWithForce(scene, targetClassName, args, timeout, unit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 异步上报到服务端, 若当前处于远程重试阶段不会进行执行上报
|
|
||||||
*/
|
|
||||||
public Boolean syncReportWithForce(String scene, String targetClassName, Object[] args, long timeout, TimeUnit unit) {
|
|
||||||
|
|
||||||
RetryTaskDTO retryTaskDTO = buildRetryTaskDTO(scene, targetClassName, args);
|
|
||||||
|
|
||||||
NettyClient CLIENT = RequestBuilder.<NettyClient, NettyResult>newBuilder()
|
|
||||||
.client(NettyClient.class)
|
|
||||||
.async(Boolean.FALSE)
|
|
||||||
.timeout(timeout)
|
|
||||||
.unit(unit)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
NettyResult result = CLIENT.reportRetryInfo(Arrays.asList(retryTaskDTO));
|
|
||||||
LogUtils.debug(log, "Data report result result:[{}]", JsonUtil.toJsonString(result));
|
|
||||||
|
|
||||||
return (Boolean) result.getData();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 异步上报到服务端, 若当前处于远程重试阶段不会进行执行上报
|
|
||||||
*/
|
|
||||||
public Boolean asyncReport(String scene, String targetClassName, Object[] args) {
|
|
||||||
|
|
||||||
if (RetrySiteSnapshot.getStage().equals(RetrySiteSnapshot.EnumStage.REMOTE.getStage())) {
|
|
||||||
LogUtils.info(log,"已经上报成功,无需重复上报 scene:[{}] targetClassName:[{}] args:[{}]", scene, targetClassName, args);
|
|
||||||
return Boolean.TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
RetryTaskDTO retryTaskDTO = buildRetryTaskDTO(scene, targetClassName, args);
|
|
||||||
slidingWindow.currentWindow().value().add(retryTaskDTO);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 不需要校验强制当前是否处于远程重试阶段,强制异步上报到服务端
|
|
||||||
*/
|
|
||||||
public Boolean asyncReportWithForce(String scene, String targetClassName, Object[] args) {
|
|
||||||
|
|
||||||
RetryTaskDTO retryTaskDTO = buildRetryTaskDTO(scene, targetClassName, args);
|
|
||||||
slidingWindow.currentWindow().value().add(retryTaskDTO);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建上报任务对象
|
|
||||||
*
|
|
||||||
* @param scene 场景
|
|
||||||
* @param targetClassName 执行对象
|
|
||||||
* @param args 参数
|
|
||||||
* @return RetryTaskDTO 上报服务端对象
|
|
||||||
*/
|
|
||||||
private RetryTaskDTO buildRetryTaskDTO(final String scene, final String targetClassName, final Object[] args) {
|
|
||||||
RetryerInfo retryerInfo = RetryerInfoCache.get(scene, targetClassName);
|
|
||||||
Method executorMethod = retryerInfo.getMethod();
|
|
||||||
|
|
||||||
RetryTaskDTO retryTaskDTO = new RetryTaskDTO();
|
|
||||||
String idempotentId;
|
|
||||||
try {
|
|
||||||
Class<? extends IdempotentIdGenerate> idempotentIdGenerate = retryerInfo.getIdempotentIdGenerate();
|
|
||||||
IdempotentIdGenerate generate = idempotentIdGenerate.newInstance();
|
|
||||||
Method method = idempotentIdGenerate.getMethod("idGenerate", Object[].class);
|
|
||||||
Object p = new Object[]{scene, targetClassName, args, executorMethod.getName()};
|
|
||||||
idempotentId = (String) ReflectionUtils.invokeMethod(method, generate, p);
|
|
||||||
} catch (Exception exception) {
|
|
||||||
LogUtils.error(log, "幂等id生成异常:{},{}", scene, args, exception);
|
|
||||||
throw new EasyRetryClientException("idempotentId生成异常:{},{}", scene, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
String serialize = retryArgSerializer.serialize(args);
|
|
||||||
retryTaskDTO.setIdempotentId(idempotentId);
|
|
||||||
retryTaskDTO.setExecutorName(targetClassName);
|
|
||||||
retryTaskDTO.setArgsStr(serialize);
|
|
||||||
retryTaskDTO.setGroupName(EasyRetryProperties.getGroup());
|
|
||||||
retryTaskDTO.setSceneName(scene);
|
|
||||||
|
|
||||||
String bizNoSpel = retryerInfo.getBizNo();
|
|
||||||
Function<Object[], String> spelParamFunction = new SPELParamFunction(bizNoSpel, executorMethod);
|
|
||||||
retryTaskDTO.setBizNo(spelParamFunction.apply(args));
|
|
||||||
return retryTaskDTO;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start() {
|
|
||||||
dispatchService.scheduleAtFixedRate(() -> {
|
|
||||||
slidingWindow.currentWindow();
|
|
||||||
}, INTERVAL_IN_MS, INTERVAL_IN_MS / SAMPLE_COUNT, TimeUnit.MILLISECONDS);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
log.info("reportHandler about to shutdown");
|
|
||||||
slidingWindow.currentWindow();
|
|
||||||
log.info("reportHandler has been shutdown");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,59 @@
|
|||||||
|
package com.aizuda.easy.retry.client.core.report;
|
||||||
|
|
||||||
|
import com.aizuda.easy.retry.client.core.client.NettyClient;
|
||||||
|
import com.aizuda.easy.retry.client.core.client.proxy.RequestBuilder;
|
||||||
|
import com.aizuda.easy.retry.client.core.intercepter.RetrySiteSnapshot;
|
||||||
|
import com.aizuda.easy.retry.client.core.retryer.RetryerInfo;
|
||||||
|
import com.aizuda.easy.retry.common.core.log.LogUtils;
|
||||||
|
import com.aizuda.easy.retry.common.core.model.NettyResult;
|
||||||
|
import com.aizuda.easy.retry.common.core.util.JsonUtil;
|
||||||
|
import com.aizuda.easy.retry.server.model.dto.RetryTaskDTO;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author www.byteblogs.com
|
||||||
|
* @date 2023-05-15
|
||||||
|
* @since 1.3.0
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class SyncReport extends AbstractReport {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supports(boolean async) {
|
||||||
|
return !async;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean doReport(RetryerInfo retryerInfo, Object[] params) {
|
||||||
|
|
||||||
|
return syncReport(retryerInfo.getScene(), retryerInfo.getExecutorClassName(), params, retryerInfo.getTimeout(), retryerInfo.getUnit());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步上报到服务端, 若当前处于远程重试阶段不会进行执行上报
|
||||||
|
*/
|
||||||
|
public Boolean syncReport(String scene, String targetClassName, Object[] args, long timeout, TimeUnit unit) {
|
||||||
|
|
||||||
|
RetryTaskDTO retryTaskDTO = buildRetryTaskDTO(scene, targetClassName, args);
|
||||||
|
|
||||||
|
NettyClient CLIENT = RequestBuilder.<NettyClient, NettyResult>newBuilder()
|
||||||
|
.client(NettyClient.class)
|
||||||
|
.async(Boolean.FALSE)
|
||||||
|
.timeout(timeout)
|
||||||
|
.unit(unit)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
NettyResult result = CLIENT.reportRetryInfo(Collections.singletonList(retryTaskDTO));
|
||||||
|
LogUtils.debug(log, "Data report result result:[{}]", JsonUtil.toJsonString(result));
|
||||||
|
|
||||||
|
return (Boolean) result.getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -16,7 +16,7 @@ import java.lang.reflect.Type;
|
|||||||
* @author: www.byteblogs.com
|
* @author: www.byteblogs.com
|
||||||
* @date : 2022-03-07 15:08
|
* @date : 2022-03-07 15:08
|
||||||
*/
|
*/
|
||||||
@Component("XRetryJacksonSerializer")
|
@Component("easyRetryJacksonSerializer")
|
||||||
public class JacksonSerializer implements RetryArgSerializer {
|
public class JacksonSerializer implements RetryArgSerializer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -4,6 +4,7 @@ import com.aizuda.easy.retry.client.core.RetryExecutor;
|
|||||||
import com.aizuda.easy.retry.client.core.RetryExecutorParameter;
|
import com.aizuda.easy.retry.client.core.RetryExecutorParameter;
|
||||||
import com.aizuda.easy.retry.client.core.event.EasyRetryListener;
|
import com.aizuda.easy.retry.client.core.event.EasyRetryListener;
|
||||||
import com.aizuda.easy.retry.client.core.intercepter.RetrySiteSnapshot;
|
import com.aizuda.easy.retry.client.core.intercepter.RetrySiteSnapshot;
|
||||||
|
import com.aizuda.easy.retry.client.core.report.Report;
|
||||||
import com.github.rholder.retry.Retryer;
|
import com.github.rholder.retry.Retryer;
|
||||||
import com.github.rholder.retry.StopStrategy;
|
import com.github.rholder.retry.StopStrategy;
|
||||||
import com.github.rholder.retry.WaitStrategy;
|
import com.github.rholder.retry.WaitStrategy;
|
||||||
@ -29,6 +30,9 @@ public abstract class AbstractRetryStrategies implements RetryStrategy {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private List<EasyRetryListener> easyRetryListeners;
|
private List<EasyRetryListener> easyRetryListeners;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private List<Report> reports;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RetryerResultContext openRetry(String sceneName, String executorClassName, Object[] params) {
|
public RetryerResultContext openRetry(String sceneName, String executorClassName, Object[] params) {
|
||||||
|
|
||||||
@ -147,5 +151,21 @@ public abstract class AbstractRetryStrategies implements RetryStrategy {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上报数据
|
||||||
|
*
|
||||||
|
* @param retryerInfo 定义重试场景的信息
|
||||||
|
* @param params 执行参数
|
||||||
|
*/
|
||||||
|
protected boolean doReport(final RetryerInfo retryerInfo, final Object[] params) {
|
||||||
|
|
||||||
|
for (Report report : reports) {
|
||||||
|
if (report.supports(retryerInfo.isAsync())) {
|
||||||
|
return report.report(retryerInfo.getScene(), retryerInfo.getExecutorClassName(), params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Boolean.FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import com.aizuda.easy.retry.client.core.RetryExecutor;
|
|||||||
import com.aizuda.easy.retry.client.core.RetryExecutorParameter;
|
import com.aizuda.easy.retry.client.core.RetryExecutorParameter;
|
||||||
import com.aizuda.easy.retry.client.core.exception.EasyRetryClientException;
|
import com.aizuda.easy.retry.client.core.exception.EasyRetryClientException;
|
||||||
import com.aizuda.easy.retry.client.core.intercepter.RetrySiteSnapshot;
|
import com.aizuda.easy.retry.client.core.intercepter.RetrySiteSnapshot;
|
||||||
import com.aizuda.easy.retry.client.core.report.ReportHandler;
|
|
||||||
import com.aizuda.easy.retry.client.core.retryer.RetryType;
|
import com.aizuda.easy.retry.client.core.retryer.RetryType;
|
||||||
import com.aizuda.easy.retry.client.core.retryer.RetryerInfo;
|
import com.aizuda.easy.retry.client.core.retryer.RetryerInfo;
|
||||||
import com.aizuda.easy.retry.client.core.retryer.RetryerResultContext;
|
import com.aizuda.easy.retry.client.core.retryer.RetryerResultContext;
|
||||||
@ -18,7 +17,6 @@ import com.github.rholder.retry.WaitStrategies;
|
|||||||
import com.github.rholder.retry.WaitStrategy;
|
import com.github.rholder.retry.WaitStrategy;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -28,16 +26,16 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* 执行本地重试
|
||||||
|
*
|
||||||
* @author: www.byteblogs.com
|
* @author: www.byteblogs.com
|
||||||
* @date : 2022-03-03 14:38
|
* @date : 2022-03-03 14:38
|
||||||
|
* @since 1.3.0
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class LocalRetryStrategies extends AbstractRetryStrategies {
|
public class LocalRetryStrategies extends AbstractRetryStrategies {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ReportHandler reportHandler;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supports(int stage, RetryType retryType) {
|
public boolean supports(int stage, RetryType retryType) {
|
||||||
return RetrySiteSnapshot.EnumStage.LOCAL.getStage() == stage ;
|
return RetrySiteSnapshot.EnumStage.LOCAL.getStage() == stage ;
|
||||||
@ -125,31 +123,6 @@ public class LocalRetryStrategies extends AbstractRetryStrategies {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 上报数据
|
|
||||||
*
|
|
||||||
* @param retryerInfo 定义重试场景的信息
|
|
||||||
* @param params 执行参数
|
|
||||||
*/
|
|
||||||
private void doReport(final RetryerInfo retryerInfo, final Object[] params) {
|
|
||||||
|
|
||||||
if (retryerInfo.isAsync()) {
|
|
||||||
if (retryerInfo.isForceReport()) {
|
|
||||||
reportHandler.asyncReportWithForce(retryerInfo.getScene(), retryerInfo.getExecutorClassName(), params);
|
|
||||||
} else {
|
|
||||||
reportHandler.asyncReport(retryerInfo.getScene(), retryerInfo.getExecutorClassName(), params);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (retryerInfo.isForceReport()) {
|
|
||||||
reportHandler.syncReport(retryerInfo.getScene(), retryerInfo.getExecutorClassName(),
|
|
||||||
params, retryerInfo.getTimeout(), retryerInfo.getUnit());
|
|
||||||
} else {
|
|
||||||
reportHandler.syncReport(retryerInfo.getScene(), retryerInfo.getExecutorClassName(),
|
|
||||||
params, retryerInfo.getTimeout(), retryerInfo.getUnit());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RetryExecutorParameter<WaitStrategy, StopStrategy> getRetryExecutorParameter(RetryerInfo retryerInfo) {
|
public RetryExecutorParameter<WaitStrategy, StopStrategy> getRetryExecutorParameter(RetryerInfo retryerInfo) {
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ package com.aizuda.easy.retry.client.core.strategy;
|
|||||||
import com.aizuda.easy.retry.client.core.RetryExecutor;
|
import com.aizuda.easy.retry.client.core.RetryExecutor;
|
||||||
import com.aizuda.easy.retry.client.core.RetryExecutorParameter;
|
import com.aizuda.easy.retry.client.core.RetryExecutorParameter;
|
||||||
import com.aizuda.easy.retry.client.core.intercepter.RetrySiteSnapshot;
|
import com.aizuda.easy.retry.client.core.intercepter.RetrySiteSnapshot;
|
||||||
import com.aizuda.easy.retry.client.core.report.ReportHandler;
|
|
||||||
import com.aizuda.easy.retry.client.core.retryer.RetryType;
|
import com.aizuda.easy.retry.client.core.retryer.RetryType;
|
||||||
import com.aizuda.easy.retry.client.core.retryer.RetryerInfo;
|
import com.aizuda.easy.retry.client.core.retryer.RetryerInfo;
|
||||||
import com.aizuda.easy.retry.client.core.retryer.RetryerResultContext;
|
import com.aizuda.easy.retry.client.core.retryer.RetryerResultContext;
|
||||||
@ -17,7 +16,6 @@ import com.github.rholder.retry.WaitStrategies;
|
|||||||
import com.github.rholder.retry.WaitStrategy;
|
import com.github.rholder.retry.WaitStrategy;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -27,6 +25,8 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* 手动执行重试
|
||||||
|
*
|
||||||
* @author: www.byteblogs.com
|
* @author: www.byteblogs.com
|
||||||
* @date : 2023-05-15 18:19
|
* @date : 2023-05-15 18:19
|
||||||
*/
|
*/
|
||||||
@ -34,9 +34,6 @@ import java.util.function.Consumer;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class ManualRetryStrategies extends AbstractRetryStrategies {
|
public class ManualRetryStrategies extends AbstractRetryStrategies {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ReportHandler reportHandler;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setStage() {
|
protected void setStage() {
|
||||||
RetrySiteSnapshot.setStage(RetrySiteSnapshot.EnumStage.MANUAL_REPORT.getStage());
|
RetrySiteSnapshot.setStage(RetrySiteSnapshot.EnumStage.MANUAL_REPORT.getStage());
|
||||||
@ -94,32 +91,6 @@ public class ManualRetryStrategies extends AbstractRetryStrategies {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 上报数据
|
|
||||||
*
|
|
||||||
* @param retryerInfo 定义重试场景的信息
|
|
||||||
* @param params 执行参数
|
|
||||||
*/
|
|
||||||
private boolean doReport(final RetryerInfo retryerInfo, final Object[] params) {
|
|
||||||
|
|
||||||
if (retryerInfo.isAsync()) {
|
|
||||||
if (retryerInfo.isForceReport()) {
|
|
||||||
return reportHandler
|
|
||||||
.asyncReportWithForce(retryerInfo.getScene(), retryerInfo.getExecutorClassName(), params);
|
|
||||||
} else {
|
|
||||||
return reportHandler.asyncReport(retryerInfo.getScene(), retryerInfo.getExecutorClassName(), params);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (retryerInfo.isForceReport()) {
|
|
||||||
return reportHandler.syncReport(retryerInfo.getScene(), retryerInfo.getExecutorClassName(),
|
|
||||||
params, retryerInfo.getTimeout(), retryerInfo.getUnit());
|
|
||||||
} else {
|
|
||||||
return reportHandler.syncReport(retryerInfo.getScene(), retryerInfo.getExecutorClassName(),
|
|
||||||
params, retryerInfo.getTimeout(), retryerInfo.getUnit());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RetryExecutorParameter<WaitStrategy, StopStrategy> getRetryExecutorParameter(RetryerInfo retryerInfo) {
|
protected RetryExecutorParameter<WaitStrategy, StopStrategy> getRetryExecutorParameter(RetryerInfo retryerInfo) {
|
||||||
return new RetryExecutorParameter<WaitStrategy, StopStrategy>() {
|
return new RetryExecutorParameter<WaitStrategy, StopStrategy>() {
|
||||||
|
@ -20,8 +20,11 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* 执行远程重试
|
||||||
|
*
|
||||||
* @author: www.byteblogs.com
|
* @author: www.byteblogs.com
|
||||||
* @date : 2022-03-03 14:38
|
* @date : 2022-03-03 14:38
|
||||||
|
* @since 1.3.0
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -1,21 +1,15 @@
|
|||||||
package com.example;
|
package com.example;
|
||||||
|
|
||||||
import com.aizuda.easy.retry.client.core.report.ReportHandler;
|
|
||||||
import com.aizuda.easy.retry.client.core.window.RetryLeapArray;
|
|
||||||
import com.aizuda.easy.retry.common.core.model.Result;
|
import com.aizuda.easy.retry.common.core.model.Result;
|
||||||
import com.aizuda.easy.retry.server.model.dto.RetryTaskDTO;
|
|
||||||
import com.example.client.DemoClient;
|
import com.example.client.DemoClient;
|
||||||
import com.example.mapper.SchoolMapper;
|
import com.example.mapper.SchoolMapper;
|
||||||
import com.example.po.School;
|
import com.example.po.School;
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
||||||
|
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ExampleApplicationTests {
|
public class ExampleApplicationTests {
|
||||||
@ -26,8 +20,6 @@ public class ExampleApplicationTests {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private RestTemplate restTemplate;
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
private RetryLeapArray retryLeapArray = ReportHandler.slidingWindow;
|
|
||||||
|
|
||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
private DemoClient demoClient;
|
private DemoClient demoClient;
|
||||||
|
|
||||||
@ -51,21 +43,4 @@ public class ExampleApplicationTests {
|
|||||||
System.out.println(template);
|
System.out.println(template);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
|
||||||
@Test
|
|
||||||
public void windows() {
|
|
||||||
|
|
||||||
for (int i = 0; i < 100000; i++) {
|
|
||||||
int finalI = i;
|
|
||||||
new Thread(() -> {
|
|
||||||
RetryTaskDTO retryTaskDTO = new RetryTaskDTO();
|
|
||||||
retryTaskDTO.setIdempotentId(finalI + "");
|
|
||||||
ConcurrentLinkedQueue<RetryTaskDTO> value = retryLeapArray.currentWindow().value();
|
|
||||||
value.add(retryTaskDTO);
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread.sleep(5 * 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user