feat: 2.4.0

1. 重试执行超时时间
This commit is contained in:
byteblogs168 2023-11-03 18:33:21 +08:00
parent 20c7f00d27
commit 23feca2075
9 changed files with 103 additions and 19 deletions

View File

@ -135,6 +135,7 @@ CREATE TABLE `scene_config`
`back_off` tinyint(4) NOT NULL DEFAULT '1' COMMENT '1、默认等级 2、固定间隔时间 3、CRON 表达式', `back_off` tinyint(4) NOT NULL DEFAULT '1' COMMENT '1、默认等级 2、固定间隔时间 3、CRON 表达式',
`trigger_interval` varchar(16) NOT NULL DEFAULT '' COMMENT '间隔时长', `trigger_interval` varchar(16) NOT NULL DEFAULT '' COMMENT '间隔时长',
`deadline_request` bigint(20) unsigned NOT NULL DEFAULT '60000' COMMENT 'Deadline Request 调用链超时 单位毫秒', `deadline_request` bigint(20) unsigned NOT NULL DEFAULT '60000' COMMENT 'Deadline Request 调用链超时 单位毫秒',
`executor_timeout` int(11) unsigned NOT NULL DEFAULT '5' COMMENT '任务执行超时时间,单位秒',
`route_key` tinyint(4) NOT NULL DEFAULT '4' COMMENT '路由策略', `route_key` tinyint(4) NOT NULL DEFAULT '4' COMMENT '路由策略',
`description` varchar(256) NOT NULL DEFAULT '' COMMENT '描述', `description` varchar(256) NOT NULL DEFAULT '' COMMENT '描述',
`create_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `create_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

View File

@ -31,6 +31,8 @@ public class SceneConfig implements Serializable {
private Integer routeKey; private Integer routeKey;
private Integer executorTimeout;
private LocalDateTime createDt; private LocalDateTime createDt;
private LocalDateTime updateDt; private LocalDateTime updateDt;

View File

@ -26,6 +26,7 @@ public class RequestBuilder<T, R> {
private boolean failover; private boolean failover;
private int routeKey; private int routeKey;
private String allocKey; private String allocKey;
private Integer executorTimeout;
public static <T, R> RequestBuilder<T, R> newBuilder() { public static <T, R> RequestBuilder<T, R> newBuilder() {
@ -42,10 +43,15 @@ public class RequestBuilder<T, R> {
return this; return this;
} }
// public RequestBuilder<T, R> groupName(String groupName) { public RequestBuilder<T, R> executorTimeout(Integer executorTimeout) {
// this.groupName = groupName; if (Objects.isNull(executorTimeout)) {
// return this; return this;
// } }
Assert.isTrue(executorTimeout > 0, () -> new EasyRetryServerException("executorTimeout can not less 0"));
this.executorTimeout = executorTimeout;
return this;
}
public RequestBuilder<T, R> failRetry(boolean failRetry) { public RequestBuilder<T, R> failRetry(boolean failRetry) {
this.failRetry = failRetry; this.failRetry = failRetry;
@ -101,7 +107,8 @@ public class RequestBuilder<T, R> {
} }
RpcClientInvokeHandler clientInvokeHandler = new RpcClientInvokeHandler( RpcClientInvokeHandler clientInvokeHandler = new RpcClientInvokeHandler(
nodeInfo.getGroupName(), nodeInfo, failRetry, retryTimes, retryInterval, retryListener, routeKey, allocKey, failover); nodeInfo.getGroupName(), nodeInfo, failRetry, retryTimes, retryInterval,
retryListener, routeKey, allocKey, failover, executorTimeout);
return (T) Proxy.newProxyInstance(clintInterface.getClassLoader(), return (T) Proxy.newProxyInstance(clintInterface.getClassLoader(),
new Class[]{clintInterface}, clientInvokeHandler); new Class[]{clintInterface}, clientInvokeHandler);

View File

@ -0,0 +1,45 @@
package com.aizuda.easy.retry.server.common.client;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/**
* @author: byteblogs168
* @date : 2023-11-03 17:40
* @since : 2.4.0
*/
@Slf4j
public class RequestInterceptor implements Interceptor {
public static final String TIMEOUT_TIME = "executorTimeout";
@NotNull
@Override
public Response intercept(@NotNull final Chain chain) throws IOException {
Request request = chain.request();
String timeoutTime = request.header(TIMEOUT_TIME);
if (StrUtil.isNotBlank(timeoutTime)) {
int timeout = Integer.parseInt(timeoutTime);
log.info("url:[{}] timeout:[{}]", request.url(), timeout);
if (timeout <= 0) {
return chain.proceed(request);
}
return chain
.withReadTimeout(timeout, TimeUnit.SECONDS)
.withConnectTimeout(timeout, TimeUnit.SECONDS)
.withWriteTimeout(timeout, TimeUnit.SECONDS)
.proceed(chain.request());
}
return chain.proceed(request);
}
}

View File

@ -7,7 +7,6 @@ import com.aizuda.easy.retry.common.core.context.SpringContext;
import com.aizuda.easy.retry.common.core.model.Result; import com.aizuda.easy.retry.common.core.model.Result;
import com.aizuda.easy.retry.common.core.util.HostUtils; import com.aizuda.easy.retry.common.core.util.HostUtils;
import com.aizuda.easy.retry.common.core.util.JsonUtil; import com.aizuda.easy.retry.common.core.util.JsonUtil;
import com.aizuda.easy.retry.server.common.allocate.client.ClientLoadBalanceManager.AllocationAlgorithmEnum;
import com.aizuda.easy.retry.server.common.cache.CacheRegisterTable; import com.aizuda.easy.retry.server.common.cache.CacheRegisterTable;
import com.aizuda.easy.retry.server.common.client.annotation.Body; import com.aizuda.easy.retry.server.common.client.annotation.Body;
import com.aizuda.easy.retry.server.common.client.annotation.Header; import com.aizuda.easy.retry.server.common.client.annotation.Header;
@ -22,7 +21,6 @@ import com.github.rholder.retry.Retryer;
import com.github.rholder.retry.RetryerBuilder; import com.github.rholder.retry.RetryerBuilder;
import com.github.rholder.retry.StopStrategies; import com.github.rholder.retry.StopStrategies;
import com.github.rholder.retry.WaitStrategies; import com.github.rholder.retry.WaitStrategies;
import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -30,7 +28,6 @@ import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.web.client.ResourceAccessException; import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestClientException;
@ -70,11 +67,12 @@ public class RpcClientInvokeHandler implements InvocationHandler {
private final boolean failover; private final boolean failover;
private final Integer routeKey; private final Integer routeKey;
private final String allocKey; private final String allocKey;
private final Integer executorTimeout;
public RpcClientInvokeHandler(final String groupName, final RegisterNodeInfo registerNodeInfo, public RpcClientInvokeHandler(final String groupName, final RegisterNodeInfo registerNodeInfo,
final boolean failRetry, final int retryTimes, final boolean failRetry, final int retryTimes,
final int retryInterval, final RetryListener retryListener, final Integer routeKey, final String allocKey, final int retryInterval, final RetryListener retryListener, final Integer routeKey, final String allocKey,
final boolean failover) { final boolean failover, final Integer executorTimeout) {
this.groupName = groupName; this.groupName = groupName;
this.hostId = registerNodeInfo.getHostId(); this.hostId = registerNodeInfo.getHostId();
this.hostPort = registerNodeInfo.getHostPort(); this.hostPort = registerNodeInfo.getHostPort();
@ -87,6 +85,7 @@ public class RpcClientInvokeHandler implements InvocationHandler {
this.failover = failover; this.failover = failover;
this.routeKey = routeKey; this.routeKey = routeKey;
this.allocKey = allocKey; this.allocKey = allocKey;
this.executorTimeout = executorTimeout;
} }
@Override @Override
@ -98,7 +97,7 @@ public class RpcClientInvokeHandler implements InvocationHandler {
return doFailoverHandler(method, args, annotation); return doFailoverHandler(method, args, annotation);
} }
return requestRemote(method, args, annotation, 0); return requestRemote(method, args, annotation, 1);
} }
@NotNull @NotNull
@ -136,6 +135,11 @@ public class RpcClientInvokeHandler implements InvocationHandler {
Retryer<Result> retryer = buildResultRetryer(); Retryer<Result> retryer = buildResultRetryer();
HttpHeaders requestHeaders = parasResult.requestHeaders;
if (Objects.nonNull(executorTimeout)) {
requestHeaders.set(RequestInterceptor.TIMEOUT_TIME, String.valueOf(executorTimeout));
}
Result result = retryer.call(() -> { Result result = retryer.call(() -> {
ResponseEntity<Result> response = restTemplate.exchange( ResponseEntity<Result> response = restTemplate.exchange(
// 拼接 url?a=1&b=1 // 拼接 url?a=1&b=1

View File

@ -1,11 +1,16 @@
package com.aizuda.easy.retry.server.common.config; package com.aizuda.easy.retry.server.common.config;
import com.aizuda.easy.retry.server.common.client.RequestInterceptor;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory; import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import java.util.concurrent.TimeUnit;
/** /**
* @author: www.byteblogs.com * @author: www.byteblogs.com
* @date : 2022-03-09 14:19 * @date : 2022-03-09 14:19
@ -14,19 +19,31 @@ import org.springframework.web.client.RestTemplate;
public class RestTemplateConfig { public class RestTemplateConfig {
@Bean @Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory){ public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
return new RestTemplate(factory); return new RestTemplate(factory);
} }
@Bean @Bean
public ClientHttpRequestFactory okHttp3ClientHttpRequestFactory(){ public ClientHttpRequestFactory okHttp3ClientHttpRequestFactory() {
OkHttp3ClientHttpRequestFactory factory = new OkHttp3ClientHttpRequestFactory();
factory.setReadTimeout(5000); OkHttpClient okHttpClient = new OkHttpClient.Builder()
factory.setConnectTimeout(5000); // 整个流程耗费的超时时间
factory.setConnectTimeout(3000); .callTimeout(60, TimeUnit.SECONDS)
factory.setWriteTimeout(5000); // 读取耗时
return factory; .readTimeout(5000, TimeUnit.MILLISECONDS)
// 三次握手 + SSL建立耗时
.connectTimeout(5000, TimeUnit.MILLISECONDS)
// 写入耗时
.writeTimeout(5000, TimeUnit.MILLISECONDS)
// 当连接失败尝试重连
.retryOnConnectionFailure(true)
// 最大空闲连接数及连接的保活时间进行配置
.connectionPool(new ConnectionPool(200, 5, TimeUnit.MINUTES))
.addInterceptor(new RequestInterceptor())
.build();
return new OkHttp3ClientHttpRequestFactory(okHttpClient);
} }
} }

View File

@ -145,6 +145,7 @@ public class ExecCallbackUnitActor extends AbstractActor {
.failover(Boolean.TRUE) .failover(Boolean.TRUE)
.routeKey(sceneConfig.getRouteKey()) .routeKey(sceneConfig.getRouteKey())
.allocKey(sceneConfig.getSceneName()) .allocKey(sceneConfig.getSceneName())
.executorTimeout(sceneConfig.getExecutorTimeout())
.client(RetryRpcClient.class) .client(RetryRpcClient.class)
.build(); .build();
return rpcClient.callback(retryCallbackDTO); return rpcClient.callback(retryCallbackDTO);

View File

@ -150,6 +150,7 @@ public class ExecUnitActor extends AbstractActor {
.failover(Boolean.TRUE) .failover(Boolean.TRUE)
.allocKey(retryTask.getSceneName()) .allocKey(retryTask.getSceneName())
.routeKey(sceneConfig.getRouteKey()) .routeKey(sceneConfig.getRouteKey())
.executorTimeout(sceneConfig.getExecutorTimeout())
.client(RetryRpcClient.class) .client(RetryRpcClient.class)
.build(); .build();

View File

@ -50,8 +50,14 @@ public class SceneConfigRequestVO {
*/ */
@Max(message = "最大60000毫秒", value = SystemConstants.DEFAULT_DDL) @Max(message = "最大60000毫秒", value = SystemConstants.DEFAULT_DDL)
@Min(message = "最小100ms", value = 100) @Min(message = "最小100ms", value = 100)
@NotNull(message = "调用链超时不能为空")
private Long deadlineRequest; private Long deadlineRequest;
@Max(message = "最大60(秒)", value = 60)
@Min(message = "最小1(秒)", value = 1)
@NotNull(message = "执行超时不能为空")
private Integer executorTimeout;
/** /**
* 是否删除 * 是否删除
*/ */