实现链路管控
This commit is contained in:
byteblogs168 2023-01-14 20:44:54 +08:00
parent 45c460e307
commit 6f1c133190
31 changed files with 256 additions and 115 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 267 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 248 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 0 B

View File

@ -3,10 +3,10 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>com.x.retry</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>x-retry</artifactId>
<version>2.5.6</version> <version>${revision}</version>
<relativePath/> <!-- lookup parent from repository --> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<groupId>com.example</groupId> <groupId>com.example</groupId>
@ -38,7 +38,7 @@
<dependency> <dependency>
<groupId>com.x.retry</groupId> <groupId>com.x.retry</groupId>
<artifactId>x-retry-client-starter</artifactId> <artifactId>x-retry-client-starter</artifactId>
<version>0.0.1.0</version> <version>0.0.2.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.baomidou</groupId> <groupId>com.baomidou</groupId>

View File

@ -1,18 +1,24 @@
package com.example; package com.example;
import com.x.retry.client.core.exception.XRetryClientException;
import com.x.retry.client.core.intercepter.RetrySiteSnapshot; import com.x.retry.client.core.intercepter.RetrySiteSnapshot;
import com.x.retry.common.core.constant.SystemConstants; 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.model.XRetryHeaders;
import com.x.retry.common.core.util.JsonUtil; import com.x.retry.common.core.util.JsonUtil;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest; import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution; import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.ClientHttpResponse;
import java.io.IOException; import java.io.IOException;
import java.util.List;
import java.util.Objects; import java.util.Objects;
/** /**
* RestTemplate 拦截器
*
* @author: shuguang.zhang * @author: shuguang.zhang
* @date : 2022-04-17 15:22 * @date : 2022-04-17 15:22
*/ */
@ -20,11 +26,44 @@ public class ExampleClientHttpRequestInterceptor implements ClientHttpRequestInt
@Override @Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { 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<String> 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));
}
} }
} }

View File

@ -1,14 +1,14 @@
package com.example.controller; 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.constant.SystemConstants;
import com.x.retry.common.core.model.Result; 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.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/** /**
* <p> * <p>
@ -23,10 +23,20 @@ import javax.servlet.http.HttpServletRequest;
public class SchoolController { public class SchoolController {
@GetMapping("/id") @GetMapping("/id")
public Result getSchool(HttpServletRequest request) { public Result getSchool(HttpServletRequest request, HttpServletResponse response) {
String header = request.getHeader(SystemConstants.X_RETRY_HEAD);
String header = request.getHeader(SystemConstants.X_RETRY_HEAD_KEY);
System.out.println(header); 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");
} }
} }

View File

@ -1,9 +1,13 @@
package com.example.controller; 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.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.stereotype.Controller; import org.springframework.web.client.RestTemplate;
/** /**
* <p> * <p>
@ -13,8 +17,24 @@ import org.springframework.stereotype.Controller;
* @author www.byteblogs.com * @author www.byteblogs.com
* @since 2022-03-24 * @since 2022-03-24
*/ */
@Controller @RestController
@RequestMapping("/teacher") @RequestMapping("/teacher")
public class TeacherController { 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;
}
} }

View File

@ -16,7 +16,7 @@ public class RemoteService {
private RestTemplate restTemplate; private RestTemplate restTemplate;
public Result call() { public Result call() {
// restTemplate.getForObject("http://127.0.0.1:8088/school/id", Result.class); return restTemplate.getForObject("http://127.0.0.1:8088/school/id", Result.class);
return new Result(); // return new Result();
} }
} }

View File

@ -21,7 +21,7 @@
<java.version>1.8</java.version> <java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.target>1.8</maven.compiler.target>
<revision>0.0.1.0-SNAPSHOT</revision> <revision>0.0.2.0</revision>
<dingding-talk.version>1.0.0</dingding-talk.version> <dingding-talk.version>1.0.0</dingding-talk.version>
<feign.version>11.7</feign.version> <feign.version>11.7</feign.version>
<hibernate-validator.version>5.4.2.Final</hibernate-validator.version> <hibernate-validator.version>5.4.2.Final</hibernate-validator.version>

View File

@ -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.core.strategy.RetryStrategy;
import com.x.retry.client.model.DispatchRetryDTO; import com.x.retry.client.model.DispatchRetryDTO;
import com.x.retry.client.model.DispatchRetryResultDTO; 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.model.Result;
import com.x.retry.common.core.util.JsonUtil; import com.x.retry.common.core.util.JsonUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -58,13 +59,23 @@ public class RetryEndPoint {
try { try {
RetryerResultContext retryerResultContext = retryStrategy.openRetry(executeReqDto.getScene(), executeReqDto.getExecutorName(), deSerialize); 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()); executeRespDto.setBizId(executeReqDto.getBizId());
if (Objects.nonNull(retryerResultContext.getResult())) { if (Objects.nonNull(retryerResultContext.getResult())) {
executeRespDto.setResultJson(JsonUtil.toJsonString(retryerResultContext.getResult())); executeRespDto.setResultJson(JsonUtil.toJsonString(retryerResultContext.getResult()));
} }
executeRespDto.setExceptionMsg(retryerResultContext.getMessage());
} finally { } finally {
RetrySiteSnapshot.removeAll(); RetrySiteSnapshot.removeAll();
} }

View File

@ -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/**");
}
}

View File

@ -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();
}
}

View File

@ -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 {
}
}

View File

@ -17,7 +17,6 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionSynchronization; import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionTemplate;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Objects; 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) { 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; 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 { try {
if (Objects.isNull(throwable)) {
return;
}
RetryerResultContext context = retryStrategy.openRetry(retryable.scene(), executorClassName, point.getArgs()); RetryerResultContext context = retryStrategy.openRetry(retryable.scene(), executorClassName, point.getArgs());
if (RetryResultStatusEnum.SUCCESS.getStatus().equals(context.getRetryResultStatusEnum().getStatus())) { if (RetryResultStatusEnum.SUCCESS.getStatus().equals(context.getRetryResultStatusEnum().getStatus())) {

View File

@ -1,5 +1,6 @@
package com.x.retry.client.core.intercepter; package com.x.retry.client.core.intercepter;
import com.x.retry.common.core.constant.SystemConstants;
import com.x.retry.common.core.model.XRetryHeaders; import com.x.retry.common.core.model.XRetryHeaders;
import lombok.Getter; import lombok.Getter;
@ -33,12 +34,22 @@ public class RetrySiteSnapshot {
*/ */
private static final ThreadLocal<XRetryHeaders> RETRY_HEADER = new ThreadLocal<>(); private static final ThreadLocal<XRetryHeaders> RETRY_HEADER = new ThreadLocal<>();
/**
* 状态码
*/
private static final ThreadLocal<String> RETRY_STATUS_CODE = new ThreadLocal<>();
/**
* 进入方法入口时间标记
*/
private static final ThreadLocal<Long> ENTRY_METHOD_TIME = new ThreadLocal<>();
public static Integer getStage() { public static Integer getStage() {
return RETRY_STAGE.get(); return RETRY_STAGE.get();
} }
public static void setStage(int stage) { public static void setStage(int stage) {
RETRY_STAGE.set(stage); RETRY_STAGE.set(stage);
} }
public static String getMethodEntrance() { public static String getMethodEntrance() {
@ -76,7 +87,7 @@ public class RetrySiteSnapshot {
/** /**
* 是否是重试流量 * 是否是重试流量
*/ */
public static boolean isRetryFlow(XRetryHeaders headers) { public static boolean isRetryFlow() {
XRetryHeaders retryHeader = getRetryHeader(); XRetryHeaders retryHeader = getRetryHeader();
if (Objects.nonNull(retryHeader)) { if (Objects.nonNull(retryHeader)) {
return retryHeader.isXRetry(); return retryHeader.isXRetry();
@ -85,10 +96,47 @@ public class RetrySiteSnapshot {
return false; 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() { public static void removeAll() {
RETRY_STATUS.remove(); RETRY_STATUS.remove();
RETRY_CLASS_METHOD_ENTRANCE.remove(); RETRY_CLASS_METHOD_ENTRANCE.remove();
RETRY_STAGE.remove(); RETRY_STAGE.remove();
RETRY_HEADER.remove();
RETRY_STATUS_CODE.remove();
} }
/** /**
@ -109,6 +157,7 @@ public class RetrySiteSnapshot {
; ;
private final int stage; private final int stage;
EnumStage(int stage) { EnumStage(int stage) {
this.stage = stage; this.stage = stage;
} }
@ -133,6 +182,7 @@ public class RetrySiteSnapshot {
; ;
private final int status; private final int status;
EnumStatus(int status) { EnumStatus(int status) {
this.status = status; this.status = status;
} }

View File

@ -12,6 +12,7 @@ import com.x.retry.client.core.retryer.RetryerInfo;
import com.x.retry.client.core.retryer.RetryerResultContext; import com.x.retry.client.core.retryer.RetryerResultContext;
import com.x.retry.common.core.enums.RetryResultStatusEnum; import com.x.retry.common.core.enums.RetryResultStatusEnum;
import com.x.retry.common.core.log.LogUtils; import com.x.retry.common.core.log.LogUtils;
import com.x.retry.common.core.model.XRetryHeaders;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -70,6 +71,12 @@ public class LocalRetryStrategies extends AbstractRetryStrategies {
return false; return false;
} }
if (!RetrySiteSnapshot.isRetryForStatusCode()) {
resultContext.setRetryResultStatusEnum(RetryResultStatusEnum.FAILURE);
resultContext.setMessage("执行重试检验不通过 原因: 下游标志禁止重试");
return false;
}
return true; return true;
} }
@ -106,7 +113,6 @@ public class LocalRetryStrategies extends AbstractRetryStrategies {
// 如果是仅仅本地重试或本地_远程模式则先支持重试 // 如果是仅仅本地重试或本地_远程模式则先支持重试
case ONLY_LOCAL: case ONLY_LOCAL:
case LOCAL_REMOTE: case LOCAL_REMOTE:
return () -> { return () -> {
if (TransactionSynchronizationManager.isActualTransactionActive()) { if (TransactionSynchronizationManager.isActualTransactionActive()) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition(); DefaultTransactionDefinition def = new DefaultTransactionDefinition();

View File

@ -12,7 +12,6 @@ import com.x.retry.common.core.enums.RetryResultStatusEnum;
import com.x.retry.common.core.log.LogUtils; import com.x.retry.common.core.log.LogUtils;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;

View File

@ -7,8 +7,20 @@ package com.x.retry.common.core.constant;
public class SystemConstants { 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";
} }

View File

@ -3,6 +3,8 @@ package com.x.retry.common.core.model;
import lombok.Data; import lombok.Data;
/** /**
* x-retry 请求头信息
*
* @author: shuguang.zhang * @author: shuguang.zhang
* @date : 2022-04-16 22:20 * @date : 2022-04-16 22:20
*/ */
@ -13,4 +15,14 @@ public class XRetryHeaders {
* 是否是重试流量 * 是否是重试流量
*/ */
private boolean xRetry; private boolean xRetry;
/**
* 重试下发的ID
*/
private String xRetryId;
/**
* 调用链超时时间 单位毫秒(ms)
*/
private long ddl = 60 * 10 * 1000;
} }

View File

@ -112,7 +112,7 @@ public class ExecUnitActor extends AbstractActor {
HttpHeaders requestHeaders = new HttpHeaders(); HttpHeaders requestHeaders = new HttpHeaders();
XRetryHeaders xRetryHeaders = new XRetryHeaders(); XRetryHeaders xRetryHeaders = new XRetryHeaders();
xRetryHeaders.setXRetry(Boolean.TRUE); xRetryHeaders.setXRetry(Boolean.TRUE);
requestHeaders.add(SystemConstants.X_RETRY_HEAD, JsonUtil.toJsonString(xRetryHeaders)); requestHeaders.add(SystemConstants.X_RETRY_HEAD_KEY, JsonUtil.toJsonString(xRetryHeaders));
HttpEntity<DispatchRetryDTO> requestEntity = new HttpEntity<>(dispatchRetryDTO, requestHeaders); HttpEntity<DispatchRetryDTO> requestEntity = new HttpEntity<>(dispatchRetryDTO, requestHeaders);

View File

@ -100,6 +100,7 @@ public class ScanGroupActor extends AbstractActor {
DispatchService.LAST_AT_MAP.put(groupConfig.getGroupName(), list.get(list.size() - 1).getCreateDt()); DispatchService.LAST_AT_MAP.put(groupConfig.getGroupName(), list.get(list.size() - 1).getCreateDt());
for (RetryTask retryTask : list) { for (RetryTask retryTask : list) {
retryCountIncrement(retryTask); retryCountIncrement(retryTask);
@ -121,11 +122,6 @@ public class ScanGroupActor extends AbstractActor {
.build(); .build();
if (!executor.filter()) { if (!executor.filter()) {
// 不触发重试
ActorRef actorRef = ActorGenerator.noRetryActor();
actorRef.tell(executor, actorRef);
continue; continue;
} }

View File

@ -37,6 +37,8 @@ public class RetryExecutor<V> {
for (FilterStrategy filterStrategy : filterStrategies) { for (FilterStrategy filterStrategy : filterStrategies) {
if (!filterStrategy.filter(retryContext)) { if (!filterStrategy.filter(retryContext)) {
return false; return false;
} }
} }

View File

@ -51,7 +51,8 @@ public class StopStrategies {
} }
Integer statusCode = data.getStatusCode(); 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);
} }
} }