diff --git a/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/intercepter/HeaderAspect.java b/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/intercepter/HeaderAspect.java
index d6492aed..43997731 100644
--- a/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/intercepter/HeaderAspect.java
+++ b/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/intercepter/HeaderAspect.java
@@ -1,5 +1,6 @@
package com.aizuda.easy.retry.client.core.intercepter;
+import com.aizuda.easy.retry.client.core.intercepter.RetrySiteSnapshot.EnumStage;
import com.aizuda.easy.retry.common.core.constant.SystemConstants;
import com.aizuda.easy.retry.common.core.log.LogUtils;
import com.aizuda.easy.retry.common.core.model.EasyRetryHeaders;
@@ -16,24 +17,29 @@ import javax.servlet.http.HttpServletResponse;
import java.util.Objects;
/**
- * 请求头和响应头传递
+ * 服务间调用传递请求头和响应头
*
* @author: www.byteblogs.com
* @date : 2022-04-18 09:19
+ * @since 1.0.0
*/
@Aspect
@Component
@Slf4j
public class HeaderAspect {
- public void before(){
+ public void before() {
+ if (skip()) {
+ return;
+ }
+
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
String xRetry = attributes.getRequest().getHeader(SystemConstants.EASY_RETRY_HEAD_KEY);
if (Objects.nonNull(xRetry)) {
// 标记进入方法的时间
RetrySiteSnapshot.setEntryMethodTime(System.currentTimeMillis());
- LogUtils.info(log, "easy-retry 拦截器 xRetry:[{}]", xRetry);
+ LogUtils.info(log, "easy-retry request header :[{}]", xRetry);
RetrySiteSnapshot.setRetryHeader(JsonUtil.parseObject(xRetry, EasyRetryHeaders.class));
}
}
@@ -66,7 +72,11 @@ public class HeaderAspect {
HttpServletResponse response = attributes.getResponse();
response.addHeader(SystemConstants.EASY_RETRY_STATUS_CODE_KEY, RetrySiteSnapshot.getRetryStatusCode());
- // 服务端重试的在com.x.retry.client.core.client.RetryEndPoint 中进行清除threadLocal
+ if (skip()) {
+ return;
+ }
+
+ // 服务端重试的在com.aizuda.easy.retry.client.core.client.RetryEndPoint.dispatch 中进行清除threadLocal
if (Objects.nonNull(RetrySiteSnapshot.getStage()) && RetrySiteSnapshot.EnumStage.REMOTE.getStage() == RetrySiteSnapshot.getStage()) {
return;
}
@@ -77,4 +87,19 @@ public class HeaderAspect {
RetrySiteSnapshot.removeEntryMethodTime();
}
+
+ /**
+ * 本地重试不执行afterReturning和before方法,避免header传递失效
+ *
+ * @return
+ */
+ private boolean skip() {
+
+ Integer stage = RetrySiteSnapshot.getStage();
+ if (Objects.nonNull(stage) && EnumStage.LOCAL.getStage() == RetrySiteSnapshot.getStage()) {
+ return true;
+ }
+
+ return false;
+ }
}
diff --git a/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/plugin/RequestHeaderPlugins.java b/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/plugin/RequestHeaderPlugins.java
index c6328de2..5d09d025 100644
--- a/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/plugin/RequestHeaderPlugins.java
+++ b/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/plugin/RequestHeaderPlugins.java
@@ -35,13 +35,17 @@ public class RequestHeaderPlugins {
// 传递请求头
if (Objects.nonNull(retryHeader)) {
long callRemoteTime = System.currentTimeMillis();
- long entryMethodTime = RetrySiteSnapshot.getEntryMethodTime();
- long transmitTime = retryHeader.getDdl() - (callRemoteTime - entryMethodTime);
- LogUtils.info(log, "RPC传递header头 entryMethodTime:[{}] - callRemoteTime:[{}] = transmitTime:[{}]", entryMethodTime, callRemoteTime, transmitTime);
- if (transmitTime > 0) {
- retryHeader.setDdl(transmitTime);
+ Long entryMethodTime = RetrySiteSnapshot.getEntryMethodTime();
+ if (Objects.isNull(entryMethodTime)) {
+ LogUtils.warn(log, "entry method time is null. easyRetryId:[{}]", retryHeader.getEasyRetryId());
} else {
- throw new EasyRetryClientException("调用链超时, 不在继续调用后面请求");
+ long transmitTime = retryHeader.getDdl() - (callRemoteTime - entryMethodTime);
+ LogUtils.info(log, "RPC传递header头 callRemoteTime:[{}] - entryMethodTime:[{}] = transmitTime:[{}]", entryMethodTime, callRemoteTime, transmitTime);
+ if (transmitTime > 0) {
+ retryHeader.setDdl(transmitTime);
+ } else {
+ throw new EasyRetryClientException("调用链超时, 不在继续调用后面请求");
+ }
}
header.put(SystemConstants.EASY_RETRY_HEAD_KEY, JsonUtil.toJsonString(retryHeader));
diff --git a/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/strategy/LocalRetryStrategies.java b/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/strategy/LocalRetryStrategies.java
index 86e65894..89a563db 100644
--- a/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/strategy/LocalRetryStrategies.java
+++ b/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/strategy/LocalRetryStrategies.java
@@ -1,7 +1,10 @@
package com.aizuda.easy.retry.client.core.strategy;
+import cn.hutool.core.util.IdUtil;
import com.aizuda.easy.retry.client.core.RetryExecutor;
import com.aizuda.easy.retry.client.core.RetryExecutorParameter;
+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.exception.EasyRetryClientException;
import com.aizuda.easy.retry.client.core.intercepter.RetrySiteSnapshot;
import com.aizuda.easy.retry.client.core.retryer.RetryType;
@@ -9,6 +12,7 @@ import com.aizuda.easy.retry.client.core.retryer.RetryerInfo;
import com.aizuda.easy.retry.client.core.retryer.RetryerResultContext;
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.github.rholder.retry.Attempt;
import com.github.rholder.retry.RetryListener;
import com.github.rholder.retry.StopStrategies;
@@ -108,6 +112,10 @@ public class LocalRetryStrategies extends AbstractRetryStrategies {
// 如果是仅仅本地重试或本地_远程模式则先支持重试
case ONLY_LOCAL:
case LOCAL_REMOTE:
+
+ // 标记进入方法的时间
+ RetrySiteSnapshot.setEntryMethodTime(System.currentTimeMillis());
+
return () -> retryExecutor.execute(params);
case ONLY_REMOTE:
// 仅仅是远程重试则直接上报
diff --git a/easy-retry-server/pom.xml b/easy-retry-server/pom.xml
index 7ce99d75..4529376d 100644
--- a/easy-retry-server/pom.xml
+++ b/easy-retry-server/pom.xml
@@ -127,6 +127,10 @@
perf4j
0.9.16
+
+ org.hibernate
+ hibernate-validator
+
diff --git a/example/src/main/java/com/example/controller/TestDdlController.java b/example/src/main/java/com/example/controller/TestDdlController.java
index 350651de..4554a812 100644
--- a/example/src/main/java/com/example/controller/TestDdlController.java
+++ b/example/src/main/java/com/example/controller/TestDdlController.java
@@ -1,5 +1,7 @@
package com.example.controller;
+import com.aizuda.easy.retry.client.core.annotation.Retryable;
+import com.aizuda.easy.retry.client.core.retryer.RetryType;
import com.aizuda.easy.retry.common.core.model.Result;
import com.example.client.DemoClient;
import org.springframework.beans.factory.annotation.Autowired;
@@ -41,4 +43,15 @@ public class TestDdlController {
return result;
}
+
+ @GetMapping("test-retry-header-controller-transfer")
+ @Retryable(scene = "testRetryHeaderControllerTransfer", retryStrategy = RetryType.ONLY_LOCAL)
+ public Result testRetryHeaderTransfer() {
+ Result result = demoClient.get();
+ if (result.getStatus() == 0) {
+ throw new UnsupportedOperationException(result.getMessage());
+ }
+ return result;
+
+ }
}
diff --git a/example/src/main/java/com/example/demo/TestRetryMethodService.java b/example/src/main/java/com/example/demo/TestRetryMethodService.java
index d0a95f85..c53f4a5f 100644
--- a/example/src/main/java/com/example/demo/TestRetryMethodService.java
+++ b/example/src/main/java/com/example/demo/TestRetryMethodService.java
@@ -2,6 +2,8 @@ package com.example.demo;
import com.aizuda.easy.retry.client.core.annotation.Retryable;
import com.aizuda.easy.retry.client.core.retryer.RetryType;
+import com.example.client.DemoClient;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
@@ -11,10 +13,19 @@ import org.springframework.stereotype.Component;
@Component
public class TestRetryMethodService {
+ @Autowired
+ private DemoClient demoClient;
+
@Retryable(scene = "testRetryMethod", retryMethod = MyExecutorMethod.class, retryStrategy = RetryType.ONLY_REMOTE)
public String testRetryMethod(String p) {
double i = 1 / 0;
return "测试自定义重试方法";
}
+ @Retryable(scene = "testRetryHeaderTransfer", retryStrategy = RetryType.ONLY_LOCAL)
+ public String testRetryHeaderTransfer(String p) {
+ demoClient.get();
+ double i = 1 / 0;
+ return "测试重试流量标识服务间传递";
+ }
}
diff --git a/example/src/test/java/com/example/TestRetryMethodServiceTest.java b/example/src/test/java/com/example/TestRetryMethodServiceTest.java
index 51ce5671..f39d43bf 100644
--- a/example/src/test/java/com/example/TestRetryMethodServiceTest.java
+++ b/example/src/test/java/com/example/TestRetryMethodServiceTest.java
@@ -27,4 +27,14 @@ public class TestRetryMethodServiceTest {
Thread.sleep(90000);
}
+ @Test
+ public void testRetryHeaderTransfer() throws InterruptedException {
+ try {
+ retryMethodService.testRetryHeaderTransfer(UUID.randomUUID().toString());
+ }catch (Exception e) {
+
+ }
+ Thread.sleep(90000);
+ }
+
}