fix: 1.5.0-hotfix

1. 修复本地重试服务间传递头节点丢失问题
This commit is contained in:
byteblogs168 2023-06-12 18:54:18 +08:00
parent 4296d17a57
commit 8051a033ca
7 changed files with 85 additions and 10 deletions

View File

@ -1,5 +1,6 @@
package com.aizuda.easy.retry.client.core.intercepter; 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.constant.SystemConstants;
import com.aizuda.easy.retry.common.core.log.LogUtils; import com.aizuda.easy.retry.common.core.log.LogUtils;
import com.aizuda.easy.retry.common.core.model.EasyRetryHeaders; import com.aizuda.easy.retry.common.core.model.EasyRetryHeaders;
@ -16,24 +17,29 @@ import javax.servlet.http.HttpServletResponse;
import java.util.Objects; import java.util.Objects;
/** /**
* 请求头和响应头传递 * 服务间调用传递请求头和响应头
* *
* @author: www.byteblogs.com * @author: www.byteblogs.com
* @date : 2022-04-18 09:19 * @date : 2022-04-18 09:19
* @since 1.0.0
*/ */
@Aspect @Aspect
@Component @Component
@Slf4j @Slf4j
public class HeaderAspect { public class HeaderAspect {
public void before(){ public void before() {
if (skip()) {
return;
}
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
String xRetry = attributes.getRequest().getHeader(SystemConstants.EASY_RETRY_HEAD_KEY); String xRetry = attributes.getRequest().getHeader(SystemConstants.EASY_RETRY_HEAD_KEY);
if (Objects.nonNull(xRetry)) { if (Objects.nonNull(xRetry)) {
// 标记进入方法的时间 // 标记进入方法的时间
RetrySiteSnapshot.setEntryMethodTime(System.currentTimeMillis()); 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)); RetrySiteSnapshot.setRetryHeader(JsonUtil.parseObject(xRetry, EasyRetryHeaders.class));
} }
} }
@ -66,7 +72,11 @@ public class HeaderAspect {
HttpServletResponse response = attributes.getResponse(); HttpServletResponse response = attributes.getResponse();
response.addHeader(SystemConstants.EASY_RETRY_STATUS_CODE_KEY, RetrySiteSnapshot.getRetryStatusCode()); 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()) { if (Objects.nonNull(RetrySiteSnapshot.getStage()) && RetrySiteSnapshot.EnumStage.REMOTE.getStage() == RetrySiteSnapshot.getStage()) {
return; return;
} }
@ -77,4 +87,19 @@ public class HeaderAspect {
RetrySiteSnapshot.removeEntryMethodTime(); 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;
}
} }

View File

@ -35,13 +35,17 @@ public class RequestHeaderPlugins {
// 传递请求头 // 传递请求头
if (Objects.nonNull(retryHeader)) { if (Objects.nonNull(retryHeader)) {
long callRemoteTime = System.currentTimeMillis(); long callRemoteTime = System.currentTimeMillis();
long entryMethodTime = RetrySiteSnapshot.getEntryMethodTime(); Long entryMethodTime = RetrySiteSnapshot.getEntryMethodTime();
long transmitTime = retryHeader.getDdl() - (callRemoteTime - entryMethodTime); if (Objects.isNull(entryMethodTime)) {
LogUtils.info(log, "RPC传递header头 entryMethodTime:[{}] - callRemoteTime:[{}] = transmitTime:[{}]", entryMethodTime, callRemoteTime, transmitTime); LogUtils.warn(log, "entry method time is null. easyRetryId:[{}]", retryHeader.getEasyRetryId());
if (transmitTime > 0) {
retryHeader.setDdl(transmitTime);
} else { } 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)); header.put(SystemConstants.EASY_RETRY_HEAD_KEY, JsonUtil.toJsonString(retryHeader));

View File

@ -1,7 +1,10 @@
package com.aizuda.easy.retry.client.core.strategy; 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.RetryExecutor;
import com.aizuda.easy.retry.client.core.RetryExecutorParameter; 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.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.retryer.RetryType; 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.client.core.retryer.RetryerResultContext;
import com.aizuda.easy.retry.common.core.enums.RetryResultStatusEnum; 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.log.LogUtils;
import com.aizuda.easy.retry.common.core.model.EasyRetryHeaders;
import com.github.rholder.retry.Attempt; import com.github.rholder.retry.Attempt;
import com.github.rholder.retry.RetryListener; import com.github.rholder.retry.RetryListener;
import com.github.rholder.retry.StopStrategies; import com.github.rholder.retry.StopStrategies;
@ -108,6 +112,10 @@ public class LocalRetryStrategies extends AbstractRetryStrategies {
// 如果是仅仅本地重试或本地_远程模式则先支持重试 // 如果是仅仅本地重试或本地_远程模式则先支持重试
case ONLY_LOCAL: case ONLY_LOCAL:
case LOCAL_REMOTE: case LOCAL_REMOTE:
// 标记进入方法的时间
RetrySiteSnapshot.setEntryMethodTime(System.currentTimeMillis());
return () -> retryExecutor.execute(params); return () -> retryExecutor.execute(params);
case ONLY_REMOTE: case ONLY_REMOTE:
// 仅仅是远程重试则直接上报 // 仅仅是远程重试则直接上报

View File

@ -127,6 +127,10 @@
<artifactId>perf4j</artifactId> <artifactId>perf4j</artifactId>
<version>0.9.16</version> <version>0.9.16</version>
</dependency> </dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -1,5 +1,7 @@
package com.example.controller; 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.aizuda.easy.retry.common.core.model.Result;
import com.example.client.DemoClient; import com.example.client.DemoClient;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -41,4 +43,15 @@ public class TestDdlController {
return result; 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;
}
} }

View File

@ -2,6 +2,8 @@ package com.example.demo;
import com.aizuda.easy.retry.client.core.annotation.Retryable; import com.aizuda.easy.retry.client.core.annotation.Retryable;
import com.aizuda.easy.retry.client.core.retryer.RetryType; 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; import org.springframework.stereotype.Component;
/** /**
@ -11,10 +13,19 @@ import org.springframework.stereotype.Component;
@Component @Component
public class TestRetryMethodService { public class TestRetryMethodService {
@Autowired
private DemoClient demoClient;
@Retryable(scene = "testRetryMethod", retryMethod = MyExecutorMethod.class, retryStrategy = RetryType.ONLY_REMOTE) @Retryable(scene = "testRetryMethod", retryMethod = MyExecutorMethod.class, retryStrategy = RetryType.ONLY_REMOTE)
public String testRetryMethod(String p) { public String testRetryMethod(String p) {
double i = 1 / 0; double i = 1 / 0;
return "测试自定义重试方法"; return "测试自定义重试方法";
} }
@Retryable(scene = "testRetryHeaderTransfer", retryStrategy = RetryType.ONLY_LOCAL)
public String testRetryHeaderTransfer(String p) {
demoClient.get();
double i = 1 / 0;
return "测试重试流量标识服务间传递";
}
} }

View File

@ -27,4 +27,14 @@ public class TestRetryMethodServiceTest {
Thread.sleep(90000); Thread.sleep(90000);
} }
@Test
public void testRetryHeaderTransfer() throws InterruptedException {
try {
retryMethodService.testRetryHeaderTransfer(UUID.randomUUID().toString());
}catch (Exception e) {
}
Thread.sleep(90000);
}
} }