diff --git a/doc/images/goup_config.png b/doc/images/goup_config.png index 65b463d8..e69de29b 100644 Binary files a/doc/images/goup_config.png and b/doc/images/goup_config.png differ diff --git a/doc/images/group_list.png b/doc/images/group_list.png index 8f6aa909..e69de29b 100644 Binary files a/doc/images/group_list.png and b/doc/images/group_list.png differ diff --git a/doc/images/login.png b/doc/images/login.png index 3577c2ef..e69de29b 100644 Binary files a/doc/images/login.png and b/doc/images/login.png differ diff --git a/doc/images/logo-big.png b/doc/images/logo-big.png index b5696829..e69de29b 100644 Binary files a/doc/images/logo-big.png and b/doc/images/logo-big.png differ diff --git a/doc/images/notify_config.png b/doc/images/notify_config.png index 2f5be014..e69de29b 100644 Binary files a/doc/images/notify_config.png and b/doc/images/notify_config.png differ diff --git a/doc/images/retry_dead_letter_list.png b/doc/images/retry_dead_letter_list.png index 088f7a6e..e69de29b 100644 Binary files a/doc/images/retry_dead_letter_list.png and b/doc/images/retry_dead_letter_list.png differ diff --git a/doc/images/retry_log_list.png b/doc/images/retry_log_list.png index 78fce929..e69de29b 100644 Binary files a/doc/images/retry_log_list.png and b/doc/images/retry_log_list.png differ diff --git a/doc/images/retry_task_list.png b/doc/images/retry_task_list.png index 097e062e..e69de29b 100644 Binary files a/doc/images/retry_task_list.png and b/doc/images/retry_task_list.png differ diff --git a/doc/images/scene_config.png b/doc/images/scene_config.png index 8196cf71..e69de29b 100644 Binary files a/doc/images/scene_config.png and b/doc/images/scene_config.png differ diff --git a/doc/images/user_add.png b/doc/images/user_add.png index 581500c6..e69de29b 100644 Binary files a/doc/images/user_add.png and b/doc/images/user_add.png differ diff --git a/doc/images/user_list.png b/doc/images/user_list.png index 99e17c0c..e69de29b 100644 Binary files a/doc/images/user_list.png and b/doc/images/user_list.png differ diff --git a/example/pom.xml b/example/pom.xml index 4d2e5263..d61b6b7d 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -3,10 +3,10 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 2.5.6 - + com.x.retry + x-retry + ${revision} + ../pom.xml com.example @@ -38,7 +38,7 @@ com.x.retry x-retry-client-starter - 0.0.1.0 + 0.0.2.0 com.baomidou diff --git a/example/src/main/java/com/example/ExampleClientHttpRequestInterceptor.java b/example/src/main/java/com/example/ExampleClientHttpRequestInterceptor.java index 3216a164..228193cd 100644 --- a/example/src/main/java/com/example/ExampleClientHttpRequestInterceptor.java +++ b/example/src/main/java/com/example/ExampleClientHttpRequestInterceptor.java @@ -1,18 +1,24 @@ package com.example; +import com.x.retry.client.core.exception.XRetryClientException; import com.x.retry.client.core.intercepter.RetrySiteSnapshot; import com.x.retry.common.core.constant.SystemConstants; +import com.x.retry.common.core.log.LogUtils; import com.x.retry.common.core.model.XRetryHeaders; import com.x.retry.common.core.util.JsonUtil; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpRequest; import org.springframework.http.client.ClientHttpRequestExecution; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.ClientHttpResponse; import java.io.IOException; +import java.util.List; import java.util.Objects; /** + * RestTemplate 拦截器 + * * @author: shuguang.zhang * @date : 2022-04-17 15:22 */ @@ -20,11 +26,44 @@ public class ExampleClientHttpRequestInterceptor implements ClientHttpRequestInt @Override public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { - XRetryHeaders retryHeader = RetrySiteSnapshot.getRetryHeader(); - if (Objects.nonNull(retryHeader)) { - request.getHeaders().add(SystemConstants.X_RETRY_HEAD, JsonUtil.toJsonString(retryHeader)); - } - return execution.execute(request, body); + before(request); + + ClientHttpResponse execute = execution.execute(request, body); + + after(execute); + + return execute; + } + + private void after(ClientHttpResponse execute) { + + HttpHeaders headers = execute.getHeaders(); + + // 获取不重试标志 + if (headers.containsKey(SystemConstants.X_RETRY_STATUS_CODE_KEY)) { + List statusCode = headers.get(SystemConstants.X_RETRY_STATUS_CODE_KEY); + RetrySiteSnapshot.setRetryStatusCode(statusCode.get(0)); + } + } + + private void before(HttpRequest request) { + + XRetryHeaders retryHeader = RetrySiteSnapshot.getRetryHeader(); + + // 传递请求头 + if (Objects.nonNull(retryHeader)) { + long callRemoteTime = System.currentTimeMillis(); + long entryMethodTime = RetrySiteSnapshot.getEntryMethodTime(); + long transmitTime = retryHeader.getDdl() - (callRemoteTime - entryMethodTime); + LogUtils.info("RPC传递header头 entryMethodTime:[{}] - callRemoteTime:[{}] = transmitTime:[{}]", entryMethodTime, callRemoteTime, transmitTime); + if (transmitTime > 0) { + retryHeader.setDdl(transmitTime); + } else { + throw new XRetryClientException("调用链超时, 不在继续调用后面请求"); + } + + request.getHeaders().add(SystemConstants.X_RETRY_HEAD_KEY, JsonUtil.toJsonString(retryHeader)); + } } } diff --git a/example/src/main/java/com/example/controller/SchoolController.java b/example/src/main/java/com/example/controller/SchoolController.java index f47c80a5..13e8fed9 100644 --- a/example/src/main/java/com/example/controller/SchoolController.java +++ b/example/src/main/java/com/example/controller/SchoolController.java @@ -1,14 +1,14 @@ package com.example.controller; +import com.x.retry.client.core.intercepter.RetrySiteSnapshot; import com.x.retry.common.core.constant.SystemConstants; import com.x.retry.common.core.model.Result; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.client.RestTemplate; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; /** *

@@ -23,10 +23,20 @@ import javax.servlet.http.HttpServletRequest; public class SchoolController { @GetMapping("/id") - public Result getSchool(HttpServletRequest request) { - String header = request.getHeader(SystemConstants.X_RETRY_HEAD); + public Result getSchool(HttpServletRequest request, HttpServletResponse response) { + + String header = request.getHeader(SystemConstants.X_RETRY_HEAD_KEY); System.out.println(header); - return new Result("school"); + + if (RetrySiteSnapshot.isRetryFlow()) { + response.addHeader(SystemConstants.X_RETRY_STATUS_CODE_KEY, SystemConstants.X_RETRY_STATUS_CODE); + } + + if (true) { + throw new UnsupportedOperationException("异常测试"); + } + + return new Result(0, "school"); } } diff --git a/example/src/main/java/com/example/controller/TeacherController.java b/example/src/main/java/com/example/controller/TeacherController.java index ff71b720..d0883a9f 100644 --- a/example/src/main/java/com/example/controller/TeacherController.java +++ b/example/src/main/java/com/example/controller/TeacherController.java @@ -1,9 +1,13 @@ package com.example.controller; +import com.x.retry.client.core.annotation.Retryable; +import com.x.retry.common.core.model.Result; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; - -import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; /** *

@@ -13,8 +17,24 @@ import org.springframework.stereotype.Controller; * @author www.byteblogs.com * @since 2022-03-24 */ -@Controller +@RestController @RequestMapping("/teacher") public class TeacherController { + @Autowired + private RestTemplate restTemplate; + + @GetMapping +// @Retryable(scene = "testStatusCode") + public Result getTeacher() { + Result result = restTemplate.getForObject("http://127.0.0.1:8088/school/id", Result.class); + result = restTemplate.getForObject("http://127.0.0.1:8088/school/id", Result.class); + result = restTemplate.getForObject("http://127.0.0.1:8088/school/id", Result.class); + result = restTemplate.getForObject("http://127.0.0.1:8088/school/id", Result.class); + + if (result.getStatus() == 0) { + throw new UnsupportedOperationException(result.getMessage()); + } + return result; + } } diff --git a/example/src/main/java/com/example/demo/RemoteService.java b/example/src/main/java/com/example/demo/RemoteService.java index 2fe656d9..7614b58b 100644 --- a/example/src/main/java/com/example/demo/RemoteService.java +++ b/example/src/main/java/com/example/demo/RemoteService.java @@ -16,7 +16,7 @@ public class RemoteService { private RestTemplate restTemplate; public Result call() { -// restTemplate.getForObject("http://127.0.0.1:8088/school/id", Result.class); - return new Result(); + return restTemplate.getForObject("http://127.0.0.1:8088/school/id", Result.class); +// return new Result(); } } diff --git a/pom.xml b/pom.xml index 6b708759..9e8c5671 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ 1.8 1.8 1.8 - 0.0.1.0-SNAPSHOT + 0.0.2.0 1.0.0 11.7 5.4.2.Final diff --git a/x-retry-client-core/src/main/java/com/x/retry/client/core/client/RetryEndPoint.java b/x-retry-client-core/src/main/java/com/x/retry/client/core/client/RetryEndPoint.java index b3ceeb17..40e1d69d 100644 --- a/x-retry-client-core/src/main/java/com/x/retry/client/core/client/RetryEndPoint.java +++ b/x-retry-client-core/src/main/java/com/x/retry/client/core/client/RetryEndPoint.java @@ -11,6 +11,7 @@ import com.x.retry.client.core.serializer.JacksonSerializer; import com.x.retry.client.core.strategy.RetryStrategy; import com.x.retry.client.model.DispatchRetryDTO; import com.x.retry.client.model.DispatchRetryResultDTO; +import com.x.retry.common.core.enums.RetryResultStatusEnum; import com.x.retry.common.core.model.Result; import com.x.retry.common.core.util.JsonUtil; import org.springframework.beans.factory.annotation.Autowired; @@ -58,13 +59,23 @@ public class RetryEndPoint { try { RetryerResultContext retryerResultContext = retryStrategy.openRetry(executeReqDto.getScene(), executeReqDto.getExecutorName(), deSerialize); - executeRespDto.setStatusCode(retryerResultContext.getRetryResultStatusEnum().getStatus()); + + if (RetrySiteSnapshot.isRetryForStatusCode()) { + executeRespDto.setStatusCode(RetryResultStatusEnum.STOP.getStatus()); + + // TODO 需要标记是哪个系统不需要重试 + executeRespDto.setExceptionMsg("下游标记不需要重试"); + } else { + executeRespDto.setStatusCode(retryerResultContext.getRetryResultStatusEnum().getStatus()); + executeRespDto.setExceptionMsg(retryerResultContext.getMessage()); + } + executeRespDto.setBizId(executeReqDto.getBizId()); if (Objects.nonNull(retryerResultContext.getResult())) { executeRespDto.setResultJson(JsonUtil.toJsonString(retryerResultContext.getResult())); } - executeRespDto.setExceptionMsg(retryerResultContext.getMessage()); + } finally { RetrySiteSnapshot.removeAll(); } diff --git a/x-retry-client-core/src/main/java/com/x/retry/client/core/config/XRetryWebMvcConfigurerAdapter.java b/x-retry-client-core/src/main/java/com/x/retry/client/core/config/XRetryWebMvcConfigurerAdapter.java deleted file mode 100644 index a8a57d57..00000000 --- a/x-retry-client-core/src/main/java/com/x/retry/client/core/config/XRetryWebMvcConfigurerAdapter.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.x.retry.client.core.config; - -import com.x.retry.client.core.intercepter.HeadersInterceptor; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -/** - * @author www.byteblogs.com - * @date 2022-03-06 - * @since 2.0 - */ -@Configuration -public class XRetryWebMvcConfigurerAdapter implements WebMvcConfigurer { - - @Autowired - private HeadersInterceptor headersInterceptor; - - @Override - public void addInterceptors(InterceptorRegistry registry) { - // 注册拦截器 - registry.addInterceptor(headersInterceptor).addPathPatterns("/retry/**"); - - } - -} diff --git a/x-retry-client-core/src/main/java/com/x/retry/client/core/intercepter/HeaderAspect.java b/x-retry-client-core/src/main/java/com/x/retry/client/core/intercepter/HeaderAspect.java new file mode 100644 index 00000000..094c5a76 --- /dev/null +++ b/x-retry-client-core/src/main/java/com/x/retry/client/core/intercepter/HeaderAspect.java @@ -0,0 +1,53 @@ +package com.x.retry.client.core.intercepter; + +import com.x.retry.common.core.constant.SystemConstants; +import com.x.retry.common.core.log.LogUtils; +import com.x.retry.common.core.model.XRetryHeaders; +import com.x.retry.common.core.util.JsonUtil; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletResponse; +import java.util.Objects; + +/** + * @author: shuguang.zhang + * @date : 2022-04-18 09:19 + */ + +@Aspect +@Component +@Slf4j +public class HeaderAspect { + + @Before(value = "@within(org.springframework.web.bind.annotation.RestController)") + public void before(JoinPoint joinPoint){ + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + String xRetry = attributes.getRequest().getHeader(SystemConstants.X_RETRY_HEAD_KEY); + if (Objects.nonNull(xRetry)) { + // 标记进入方法的时间 + RetrySiteSnapshot.setEntryMethodTime(System.currentTimeMillis()); + + LogUtils.info("x-retry 拦截器 xRetry:[{}]", xRetry); + RetrySiteSnapshot.setRetryHeader(JsonUtil.parseObject(xRetry, XRetryHeaders.class)); + } + } + + @AfterReturning(pointcut = "@within(org.springframework.web.bind.annotation.RestController)", returning = "o") + public void afterReturning(Object o) { + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + HttpServletResponse response = attributes.getResponse(); + response.addHeader(SystemConstants.X_RETRY_STATUS_CODE_KEY, RetrySiteSnapshot.getRetryStatusCode()); + + RetrySiteSnapshot.removeRetryHeader(); + RetrySiteSnapshot.removeRetryStatusCode(); + RetrySiteSnapshot.removeEntryMethodTime(); + + } +} diff --git a/x-retry-client-core/src/main/java/com/x/retry/client/core/intercepter/HeadersInterceptor.java b/x-retry-client-core/src/main/java/com/x/retry/client/core/intercepter/HeadersInterceptor.java deleted file mode 100644 index a909df68..00000000 --- a/x-retry-client-core/src/main/java/com/x/retry/client/core/intercepter/HeadersInterceptor.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.x.retry.client.core.intercepter; - -import com.x.retry.common.core.constant.SystemConstants; -import com.x.retry.common.core.log.LogUtils; -import com.x.retry.common.core.model.XRetryHeaders; -import com.x.retry.common.core.util.JsonUtil; -import org.springframework.context.annotation.Configuration; -import org.springframework.stereotype.Component; -import org.springframework.web.servlet.HandlerInterceptor; -import org.springframework.web.servlet.ModelAndView; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.Objects; - -/** - * @Author:byteblogs - * @Date:2018/09/27 12:52 - */ -@Component -public class HeadersInterceptor implements HandlerInterceptor { - - @Override - public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception { - String xRetry = httpServletRequest.getHeader(SystemConstants.X_RETRY_HEAD); - if (Objects.nonNull(xRetry)) { - LogUtils.info("x-retry 拦截器 xRetry:[{}]", xRetry); - RetrySiteSnapshot.setRetryHeader(JsonUtil.parseObject(xRetry, XRetryHeaders.class)); - } - - return true; - } - - @Override - public void postHandle(HttpServletRequest httpServletRequest, - HttpServletResponse httpServletResponse, - Object o, ModelAndView modelAndView) throws Exception { - - } - - @Override - public void afterCompletion(HttpServletRequest httpServletRequest, - HttpServletResponse httpServletResponse, - Object o, Exception e) throws Exception { - } -} diff --git a/x-retry-client-core/src/main/java/com/x/retry/client/core/intercepter/RetryAspect.java b/x-retry-client-core/src/main/java/com/x/retry/client/core/intercepter/RetryAspect.java index adc72799..eec543c8 100644 --- a/x-retry-client-core/src/main/java/com/x/retry/client/core/intercepter/RetryAspect.java +++ b/x-retry-client-core/src/main/java/com/x/retry/client/core/intercepter/RetryAspect.java @@ -17,7 +17,6 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import org.springframework.transaction.support.TransactionSynchronization; import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.transaction.support.TransactionTemplate; import java.lang.reflect.Method; import java.util.Objects; @@ -72,7 +71,14 @@ public class RetryAspect { private void doHandlerRetry(ProceedingJoinPoint point, String traceId, Retryable retryable, String executorClassName, String methodEntrance, Throwable throwable) { - if (!RetrySiteSnapshot.isMethodEntrance(methodEntrance) || RetrySiteSnapshot.isRunning()) { + if (!RetrySiteSnapshot.isMethodEntrance(methodEntrance) + || RetrySiteSnapshot.isRunning() + || Objects.isNull(throwable) + // 重试流量不开启重试 + || RetrySiteSnapshot.isRetryFlow() + // 下游响应不重试码,不开启重试 + || RetrySiteSnapshot.isRetryForStatusCode() + ) { return; } @@ -93,11 +99,8 @@ public class RetryAspect { }); } - private void openRetry(ProceedingJoinPoint point, String traceId, Retryable retryable, String executorClassName, Throwable throwable) { + private void openRetry(ProceedingJoinPoint point, String traceId, Retryable retryable, String executorClassName, Throwable throwable) { try { - if (Objects.isNull(throwable)) { - return; - } RetryerResultContext context = retryStrategy.openRetry(retryable.scene(), executorClassName, point.getArgs()); if (RetryResultStatusEnum.SUCCESS.getStatus().equals(context.getRetryResultStatusEnum().getStatus())) { diff --git a/x-retry-client-core/src/main/java/com/x/retry/client/core/intercepter/RetrySiteSnapshot.java b/x-retry-client-core/src/main/java/com/x/retry/client/core/intercepter/RetrySiteSnapshot.java index 07cf4f10..b2b0ebf7 100644 --- a/x-retry-client-core/src/main/java/com/x/retry/client/core/intercepter/RetrySiteSnapshot.java +++ b/x-retry-client-core/src/main/java/com/x/retry/client/core/intercepter/RetrySiteSnapshot.java @@ -1,5 +1,6 @@ package com.x.retry.client.core.intercepter; +import com.x.retry.common.core.constant.SystemConstants; import com.x.retry.common.core.model.XRetryHeaders; import lombok.Getter; @@ -33,12 +34,22 @@ public class RetrySiteSnapshot { */ private static final ThreadLocal RETRY_HEADER = new ThreadLocal<>(); + /** + * 状态码 + */ + private static final ThreadLocal RETRY_STATUS_CODE = new ThreadLocal<>(); + + /** + * 进入方法入口时间标记 + */ + private static final ThreadLocal ENTRY_METHOD_TIME = new ThreadLocal<>(); + public static Integer getStage() { return RETRY_STAGE.get(); } public static void setStage(int stage) { - RETRY_STAGE.set(stage); + RETRY_STAGE.set(stage); } public static String getMethodEntrance() { @@ -76,7 +87,7 @@ public class RetrySiteSnapshot { /** * 是否是重试流量 */ - public static boolean isRetryFlow(XRetryHeaders headers) { + public static boolean isRetryFlow() { XRetryHeaders retryHeader = getRetryHeader(); if (Objects.nonNull(retryHeader)) { return retryHeader.isXRetry(); @@ -85,10 +96,47 @@ public class RetrySiteSnapshot { return false; } + public static String getRetryStatusCode() { + return RETRY_STATUS_CODE.get(); + } + + public static void setRetryStatusCode(String statusCode) { + RETRY_STATUS_CODE.set(statusCode); + } + + public static boolean isRetryForStatusCode() { + return getRetryStatusCode().equals(SystemConstants.X_RETRY_STATUS_CODE); + } + + public static Long getEntryMethodTime() { + return ENTRY_METHOD_TIME.get(); + } + + public static void setEntryMethodTime(long entryMethodTime) { + ENTRY_METHOD_TIME.set(entryMethodTime); + } + + public static void removeEntryMethodTime() { + ENTRY_METHOD_TIME.remove(); + } + + + public static void removeRetryHeader(){ + RETRY_HEADER.remove(); + } + + public static void removeRetryStatusCode(){ + RETRY_STATUS_CODE.remove(); + } + public static void removeAll() { + RETRY_STATUS.remove(); RETRY_CLASS_METHOD_ENTRANCE.remove(); RETRY_STAGE.remove(); + RETRY_HEADER.remove(); + RETRY_STATUS_CODE.remove(); + } /** @@ -109,6 +157,7 @@ public class RetrySiteSnapshot { ; private final int stage; + EnumStage(int stage) { this.stage = stage; } @@ -133,6 +182,7 @@ public class RetrySiteSnapshot { ; private final int status; + EnumStatus(int status) { this.status = status; } diff --git a/x-retry-client-core/src/main/java/com/x/retry/client/core/strategy/LocalRetryStrategies.java b/x-retry-client-core/src/main/java/com/x/retry/client/core/strategy/LocalRetryStrategies.java index 221f549e..e72e7b23 100644 --- a/x-retry-client-core/src/main/java/com/x/retry/client/core/strategy/LocalRetryStrategies.java +++ b/x-retry-client-core/src/main/java/com/x/retry/client/core/strategy/LocalRetryStrategies.java @@ -12,6 +12,7 @@ import com.x.retry.client.core.retryer.RetryerInfo; import com.x.retry.client.core.retryer.RetryerResultContext; import com.x.retry.common.core.enums.RetryResultStatusEnum; import com.x.retry.common.core.log.LogUtils; +import com.x.retry.common.core.model.XRetryHeaders; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -70,6 +71,12 @@ public class LocalRetryStrategies extends AbstractRetryStrategies { return false; } + if (!RetrySiteSnapshot.isRetryForStatusCode()) { + resultContext.setRetryResultStatusEnum(RetryResultStatusEnum.FAILURE); + resultContext.setMessage("执行重试检验不通过 原因: 下游标志禁止重试"); + return false; + } + return true; } @@ -106,7 +113,6 @@ public class LocalRetryStrategies extends AbstractRetryStrategies { // 如果是仅仅本地重试或本地_远程模式则先支持重试 case ONLY_LOCAL: case LOCAL_REMOTE: - return () -> { if (TransactionSynchronizationManager.isActualTransactionActive()) { DefaultTransactionDefinition def = new DefaultTransactionDefinition(); diff --git a/x-retry-client-core/src/main/java/com/x/retry/client/core/strategy/RemoteRetryStrategies.java b/x-retry-client-core/src/main/java/com/x/retry/client/core/strategy/RemoteRetryStrategies.java index 56c71ae6..bf3a153f 100644 --- a/x-retry-client-core/src/main/java/com/x/retry/client/core/strategy/RemoteRetryStrategies.java +++ b/x-retry-client-core/src/main/java/com/x/retry/client/core/strategy/RemoteRetryStrategies.java @@ -12,7 +12,6 @@ import com.x.retry.common.core.enums.RetryResultStatusEnum; import com.x.retry.common.core.log.LogUtils; import org.springframework.stereotype.Component; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.Callable; diff --git a/x-retry-common/x-retry-common-core/src/main/java/com/x/retry/common/core/constant/SystemConstants.java b/x-retry-common/x-retry-common-core/src/main/java/com/x/retry/common/core/constant/SystemConstants.java index 922300ca..3404ffb0 100644 --- a/x-retry-common/x-retry-common-core/src/main/java/com/x/retry/common/core/constant/SystemConstants.java +++ b/x-retry-common/x-retry-common-core/src/main/java/com/x/retry/common/core/constant/SystemConstants.java @@ -7,8 +7,20 @@ package com.x.retry.common.core.constant; public class SystemConstants { /** - * 请求头 + * 请求头 key */ - public static final String X_RETRY_HEAD = "X-RETRY"; + public static final String X_RETRY_HEAD_KEY = "X-RETRY"; + + /** + * 异常重试码 key + */ + public static final String X_RETRY_STATUS_CODE_KEY = "X-RETRY-STATUS"; + + /** + * 异常重试码 + */ + public static final String X_RETRY_STATUS_CODE = "519"; + + } diff --git a/x-retry-common/x-retry-common-core/src/main/java/com/x/retry/common/core/model/XRetryHeaders.java b/x-retry-common/x-retry-common-core/src/main/java/com/x/retry/common/core/model/XRetryHeaders.java index abce0cb4..dab1b61e 100644 --- a/x-retry-common/x-retry-common-core/src/main/java/com/x/retry/common/core/model/XRetryHeaders.java +++ b/x-retry-common/x-retry-common-core/src/main/java/com/x/retry/common/core/model/XRetryHeaders.java @@ -3,6 +3,8 @@ package com.x.retry.common.core.model; import lombok.Data; /** + * x-retry 请求头信息 + * * @author: shuguang.zhang * @date : 2022-04-16 22:20 */ @@ -13,4 +15,14 @@ public class XRetryHeaders { * 是否是重试流量 */ private boolean xRetry; + + /** + * 重试下发的ID + */ + private String xRetryId; + + /** + * 调用链超时时间 单位毫秒(ms) + */ + private long ddl = 60 * 10 * 1000; } diff --git a/x-retry-server/src/main/java/com/x/retry/server/support/dispatch/actor/exec/ExecUnitActor.java b/x-retry-server/src/main/java/com/x/retry/server/support/dispatch/actor/exec/ExecUnitActor.java index 2a237aea..d0a0d353 100644 --- a/x-retry-server/src/main/java/com/x/retry/server/support/dispatch/actor/exec/ExecUnitActor.java +++ b/x-retry-server/src/main/java/com/x/retry/server/support/dispatch/actor/exec/ExecUnitActor.java @@ -112,7 +112,7 @@ public class ExecUnitActor extends AbstractActor { HttpHeaders requestHeaders = new HttpHeaders(); XRetryHeaders xRetryHeaders = new XRetryHeaders(); xRetryHeaders.setXRetry(Boolean.TRUE); - requestHeaders.add(SystemConstants.X_RETRY_HEAD, JsonUtil.toJsonString(xRetryHeaders)); + requestHeaders.add(SystemConstants.X_RETRY_HEAD_KEY, JsonUtil.toJsonString(xRetryHeaders)); HttpEntity requestEntity = new HttpEntity<>(dispatchRetryDTO, requestHeaders); diff --git a/x-retry-server/src/main/java/com/x/retry/server/support/dispatch/actor/scan/ScanGroupActor.java b/x-retry-server/src/main/java/com/x/retry/server/support/dispatch/actor/scan/ScanGroupActor.java index 9d2bf235..1581ea72 100644 --- a/x-retry-server/src/main/java/com/x/retry/server/support/dispatch/actor/scan/ScanGroupActor.java +++ b/x-retry-server/src/main/java/com/x/retry/server/support/dispatch/actor/scan/ScanGroupActor.java @@ -100,6 +100,7 @@ public class ScanGroupActor extends AbstractActor { DispatchService.LAST_AT_MAP.put(groupConfig.getGroupName(), list.get(list.size() - 1).getCreateDt()); + for (RetryTask retryTask : list) { retryCountIncrement(retryTask); @@ -121,11 +122,6 @@ public class ScanGroupActor extends AbstractActor { .build(); if (!executor.filter()) { - - // 不触发重试 - ActorRef actorRef = ActorGenerator.noRetryActor(); - actorRef.tell(executor, actorRef); - continue; } diff --git a/x-retry-server/src/main/java/com/x/retry/server/support/retry/RetryExecutor.java b/x-retry-server/src/main/java/com/x/retry/server/support/retry/RetryExecutor.java index eba91104..e7b02dae 100644 --- a/x-retry-server/src/main/java/com/x/retry/server/support/retry/RetryExecutor.java +++ b/x-retry-server/src/main/java/com/x/retry/server/support/retry/RetryExecutor.java @@ -37,6 +37,8 @@ public class RetryExecutor { for (FilterStrategy filterStrategy : filterStrategies) { if (!filterStrategy.filter(retryContext)) { + + return false; } } diff --git a/x-retry-server/src/main/java/com/x/retry/server/support/strategy/StopStrategies.java b/x-retry-server/src/main/java/com/x/retry/server/support/strategy/StopStrategies.java index 5857d5ee..15b48d35 100644 --- a/x-retry-server/src/main/java/com/x/retry/server/support/strategy/StopStrategies.java +++ b/x-retry-server/src/main/java/com/x/retry/server/support/strategy/StopStrategies.java @@ -51,7 +51,8 @@ public class StopStrategies { } Integer statusCode = data.getStatusCode(); - return RetryResultStatusEnum.SUCCESS.getStatus().equals(RetryResultStatusEnum.getRetryResultStatusEnum(statusCode).getStatus()); + Integer status = RetryResultStatusEnum.getRetryResultStatusEnum(statusCode).getStatus(); + return RetryResultStatusEnum.SUCCESS.getStatus().equals(status) || RetryResultStatusEnum.STOP.getStatus().equals(status); } }