fix: 1.5.0-hotfix
1. 修复本地重试服务间传递头节点丢失问题
This commit is contained in:
parent
4296d17a57
commit
8051a033ca
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
@ -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:
|
||||||
// 仅仅是远程重试则直接上报
|
// 仅仅是远程重试则直接上报
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 "测试重试流量标识服务间传递";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user