feat(3.2.0): 新增token 校验
1. 新增group_config 新增token配置 2. 组配置新增配置token的字段且可以自动生成 3. 客户端与服务端都校验token的合法性 4. 优化了group缓存的bug
This commit is contained in:
parent
aa0ad7737c
commit
6cad4b81cc
@ -29,6 +29,11 @@
|
|||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.aizuda.easy.retry.client.common.annotation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Easy Retry Client 认证
|
||||||
|
*
|
||||||
|
* @author: xiaownouniu
|
||||||
|
* @date : 2024-03-30
|
||||||
|
* @since : 3.2.0
|
||||||
|
*/
|
||||||
|
public @interface Authentication {
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.aizuda.easy.retry.client.common.intercepter;
|
||||||
|
|
||||||
|
import com.aizuda.easy.retry.client.common.config.EasyRetryProperties;
|
||||||
|
import com.aizuda.easy.retry.client.common.exception.EasyRetryClientException;
|
||||||
|
import com.aizuda.easy.retry.common.core.constant.SystemConstants;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
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 java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Easy Retry 认证拦截器
|
||||||
|
*
|
||||||
|
* @author: xiaowoniu
|
||||||
|
* @date : 2022-04-18 09:19
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class AuthenticationInterceptor {
|
||||||
|
private final EasyRetryProperties easyRetryProperties;
|
||||||
|
@Before(value = "@annotation(com.aizuda.easy.retry.client.common.annotation.Authentication) || @within(com.aizuda.easy.retry.client.common.annotation.Authentication)")
|
||||||
|
public void easyRetryAuth() {
|
||||||
|
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||||
|
String easyRetryAuth = attributes.getRequest().getHeader(SystemConstants.EASY_RETRY_AUTH_TOKEN);
|
||||||
|
String configToken = Optional.ofNullable(easyRetryProperties.getToken()).orElse(SystemConstants.DEFAULT_TOKEN);
|
||||||
|
if (!configToken.equals(easyRetryAuth)) {
|
||||||
|
throw new EasyRetryClientException("认证失败.【请检查配置的Token是否正确】");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -182,7 +182,7 @@ public class NettyChannel {
|
|||||||
.set(HeadersEnum.HOST.getKey(), serverConfig.getHost())
|
.set(HeadersEnum.HOST.getKey(), serverConfig.getHost())
|
||||||
.set(HeadersEnum.NAMESPACE.getKey(), Optional.ofNullable(easyRetryProperties.getNamespace()).orElse(
|
.set(HeadersEnum.NAMESPACE.getKey(), Optional.ofNullable(easyRetryProperties.getNamespace()).orElse(
|
||||||
SystemConstants.DEFAULT_NAMESPACE))
|
SystemConstants.DEFAULT_NAMESPACE))
|
||||||
.set(HeadersEnum.TOKEN.getKey(), Optional.ofNullable(easyRetryProperties.getNamespace()).orElse(
|
.set(HeadersEnum.TOKEN.getKey(), Optional.ofNullable(easyRetryProperties.getToken()).orElse(
|
||||||
SystemConstants.DEFAULT_TOKEN))
|
SystemConstants.DEFAULT_TOKEN))
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.aizuda.easy.retry.client.core.client;
|
package com.aizuda.easy.retry.client.core.client;
|
||||||
|
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import com.aizuda.easy.retry.client.common.annotation.Authentication;
|
||||||
import com.aizuda.easy.retry.client.common.log.support.EasyRetryLogManager;
|
import com.aizuda.easy.retry.client.common.log.support.EasyRetryLogManager;
|
||||||
import com.aizuda.easy.retry.client.core.IdempotentIdGenerate;
|
import com.aizuda.easy.retry.client.core.IdempotentIdGenerate;
|
||||||
import com.aizuda.easy.retry.client.core.RetryArgSerializer;
|
import com.aizuda.easy.retry.client.core.RetryArgSerializer;
|
||||||
@ -62,6 +63,7 @@ public class RetryEndPoint {
|
|||||||
* 服务端调度重试入口
|
* 服务端调度重试入口
|
||||||
*/
|
*/
|
||||||
@PostMapping("/dispatch/v1")
|
@PostMapping("/dispatch/v1")
|
||||||
|
@Authentication
|
||||||
public Result<DispatchRetryResultDTO> dispatch(@RequestBody @Validated DispatchRetryDTO executeReqDto) {
|
public Result<DispatchRetryResultDTO> dispatch(@RequestBody @Validated DispatchRetryDTO executeReqDto) {
|
||||||
|
|
||||||
RetryerInfo retryerInfo = RetryerInfoCache.get(executeReqDto.getScene(), executeReqDto.getExecutorName());
|
RetryerInfo retryerInfo = RetryerInfoCache.get(executeReqDto.getScene(), executeReqDto.getExecutorName());
|
||||||
@ -135,12 +137,14 @@ public class RetryEndPoint {
|
|||||||
* 同步版本
|
* 同步版本
|
||||||
*/
|
*/
|
||||||
@PostMapping("/sync/version/v1")
|
@PostMapping("/sync/version/v1")
|
||||||
|
@Authentication
|
||||||
public Result syncVersion(@RequestBody ConfigDTO configDTO) {
|
public Result syncVersion(@RequestBody ConfigDTO configDTO) {
|
||||||
GroupVersionCache.configDTO = configDTO;
|
GroupVersionCache.configDTO = configDTO;
|
||||||
return new Result();
|
return new Result();
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/callback/v1")
|
@PostMapping("/callback/v1")
|
||||||
|
@Authentication
|
||||||
public Result callback(@RequestBody @Validated RetryCallbackDTO callbackDTO) {
|
public Result callback(@RequestBody @Validated RetryCallbackDTO callbackDTO) {
|
||||||
|
|
||||||
RetryerInfo retryerInfo = null;
|
RetryerInfo retryerInfo = null;
|
||||||
@ -252,6 +256,7 @@ public class RetryEndPoint {
|
|||||||
* @return idempotentId
|
* @return idempotentId
|
||||||
*/
|
*/
|
||||||
@PostMapping("/generate/idempotent-id/v1")
|
@PostMapping("/generate/idempotent-id/v1")
|
||||||
|
@Authentication
|
||||||
public Result<String> idempotentIdGenerate(
|
public Result<String> idempotentIdGenerate(
|
||||||
@RequestBody @Validated GenerateRetryIdempotentIdDTO generateRetryIdempotentIdDTO) {
|
@RequestBody @Validated GenerateRetryIdempotentIdDTO generateRetryIdempotentIdDTO) {
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.aizuda.easy.retry.client.job.core.client;
|
package com.aizuda.easy.retry.client.job.core.client;
|
||||||
|
|
||||||
|
import com.aizuda.easy.retry.client.common.annotation.Authentication;
|
||||||
import com.aizuda.easy.retry.client.common.log.support.EasyRetryLogManager;
|
import com.aizuda.easy.retry.client.common.log.support.EasyRetryLogManager;
|
||||||
import com.aizuda.easy.retry.client.job.core.IJobExecutor;
|
import com.aizuda.easy.retry.client.job.core.IJobExecutor;
|
||||||
import com.aizuda.easy.retry.client.job.core.cache.JobExecutorInfoCache;
|
import com.aizuda.easy.retry.client.job.core.cache.JobExecutorInfoCache;
|
||||||
@ -35,6 +36,7 @@ import java.util.concurrent.ThreadPoolExecutor;
|
|||||||
public class JobEndPoint {
|
public class JobEndPoint {
|
||||||
|
|
||||||
@PostMapping("/dispatch/v1")
|
@PostMapping("/dispatch/v1")
|
||||||
|
@Authentication
|
||||||
public Result<Boolean> dispatchJob(@RequestBody @Validated DispatchJobRequest dispatchJob) {
|
public Result<Boolean> dispatchJob(@RequestBody @Validated DispatchJobRequest dispatchJob) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -108,6 +110,7 @@ public class JobEndPoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/stop/v1")
|
@PostMapping("/stop/v1")
|
||||||
|
@Authentication
|
||||||
public Result<Boolean> stopJob(@RequestBody @Validated StopJobDTO interruptJob) {
|
public Result<Boolean> stopJob(@RequestBody @Validated StopJobDTO interruptJob) {
|
||||||
ThreadPoolExecutor threadPool = ThreadPoolCache.getThreadPool(interruptJob.getTaskBatchId());
|
ThreadPoolExecutor threadPool = ThreadPoolCache.getThreadPool(interruptJob.getTaskBatchId());
|
||||||
if (Objects.isNull(threadPool) || threadPool.isShutdown() || threadPool.isTerminated()) {
|
if (Objects.isNull(threadPool) || threadPool.isShutdown() || threadPool.isTerminated()) {
|
||||||
|
@ -133,4 +133,9 @@ public interface SystemConstants {
|
|||||||
* 仅表示定时任务类型为工作流
|
* 仅表示定时任务类型为工作流
|
||||||
*/
|
*/
|
||||||
Integer WORKFLOW_TRIGGER_TYPE = 99;
|
Integer WORKFLOW_TRIGGER_TYPE = 99;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Easy Retry 认证Token
|
||||||
|
*/
|
||||||
|
String EASY_RETRY_AUTH_TOKEN= "ER-TOKEN";
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,9 @@ import com.google.common.cache.CacheBuilder;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@ -21,14 +24,14 @@ import java.util.concurrent.TimeUnit;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class CacheConsumerGroup implements Lifecycle {
|
public class CacheConsumerGroup implements Lifecycle {
|
||||||
|
|
||||||
private static Cache<String /*groupName*/, String/*namespaceId*/> CACHE;
|
private static Cache<String /*groupName*/, Set<String>/*namespaceId*/> CACHE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有缓存
|
* 获取所有缓存
|
||||||
*
|
*
|
||||||
* @return 缓存对象
|
* @return 缓存对象
|
||||||
*/
|
*/
|
||||||
public static ConcurrentMap<String, String> getAllConsumerGroupName() {
|
public static ConcurrentMap<String, Set<String>> getAllConsumerGroupName() {
|
||||||
return CACHE.asMap();
|
return CACHE.asMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +42,9 @@ public class CacheConsumerGroup implements Lifecycle {
|
|||||||
* @return 缓存对象
|
* @return 缓存对象
|
||||||
*/
|
*/
|
||||||
public static synchronized void addOrUpdate(String groupName, String namespaceId) {
|
public static synchronized void addOrUpdate(String groupName, String namespaceId) {
|
||||||
CACHE.put(groupName, namespaceId);
|
Set<String> namespaceIds = Optional.ofNullable(CACHE.getIfPresent(groupName)).orElseGet(HashSet::new);
|
||||||
|
namespaceIds.add(namespaceId);
|
||||||
|
CACHE.put(groupName, namespaceIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void remove(String groupName) {
|
public static void remove(String groupName) {
|
||||||
|
@ -8,6 +8,7 @@ import com.aizuda.easy.retry.server.common.Lifecycle;
|
|||||||
import com.aizuda.easy.retry.server.common.RegisterNodeInfoConverter;
|
import com.aizuda.easy.retry.server.common.RegisterNodeInfoConverter;
|
||||||
import com.aizuda.easy.retry.server.common.dto.RegisterNodeInfo;
|
import com.aizuda.easy.retry.server.common.dto.RegisterNodeInfo;
|
||||||
import com.aizuda.easy.retry.server.common.register.ServerRegister;
|
import com.aizuda.easy.retry.server.common.register.ServerRegister;
|
||||||
|
import com.aizuda.easy.retry.server.common.triple.Pair;
|
||||||
import com.aizuda.easy.retry.template.datasource.persistence.mapper.ServerNodeMapper;
|
import com.aizuda.easy.retry.template.datasource.persistence.mapper.ServerNodeMapper;
|
||||||
import com.aizuda.easy.retry.template.datasource.persistence.po.ServerNode;
|
import com.aizuda.easy.retry.template.datasource.persistence.po.ServerNode;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
@ -44,7 +45,7 @@ import java.util.stream.Collectors;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class CacheRegisterTable implements Lifecycle {
|
public class CacheRegisterTable implements Lifecycle {
|
||||||
|
|
||||||
private static Cache<String, ConcurrentMap<String, RegisterNodeInfo>> CACHE;
|
private static Cache<Pair<String/*groupName*/, String/*namespaceId*/>, ConcurrentMap<String, RegisterNodeInfo>> CACHE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有缓存
|
* 获取所有缓存
|
||||||
@ -52,7 +53,7 @@ public class CacheRegisterTable implements Lifecycle {
|
|||||||
* @return 缓存对象
|
* @return 缓存对象
|
||||||
*/
|
*/
|
||||||
public static Set<RegisterNodeInfo> getAllPods() {
|
public static Set<RegisterNodeInfo> getAllPods() {
|
||||||
ConcurrentMap<String, ConcurrentMap<String, RegisterNodeInfo>> concurrentMap = CACHE.asMap();
|
ConcurrentMap<Pair<String, String>, ConcurrentMap<String, RegisterNodeInfo>> concurrentMap = CACHE.asMap();
|
||||||
if (CollectionUtils.isEmpty(concurrentMap)) {
|
if (CollectionUtils.isEmpty(concurrentMap)) {
|
||||||
return Sets.newHashSet();
|
return Sets.newHashSet();
|
||||||
}
|
}
|
||||||
@ -137,8 +138,8 @@ public class CacheRegisterTable implements Lifecycle {
|
|||||||
return new TreeSet<>(concurrentMap.values());
|
return new TreeSet<>(concurrentMap.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getKey(final String groupName, final String namespaceId) {
|
private static Pair<String, String> getKey(final String groupName, final String namespaceId) {
|
||||||
return groupName + StrUtil.AT + namespaceId;
|
return Pair.of(groupName, namespaceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -202,6 +203,7 @@ public class CacheRegisterTable implements Lifecycle {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除过期的节点信息
|
* 删除过期的节点信息
|
||||||
|
*
|
||||||
* @param concurrentMap 并发映射的节点信息
|
* @param concurrentMap 并发映射的节点信息
|
||||||
*/
|
*/
|
||||||
private static void delExpireNode(final ConcurrentMap<String, RegisterNodeInfo> concurrentMap) {
|
private static void delExpireNode(final ConcurrentMap<String, RegisterNodeInfo> concurrentMap) {
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
package com.aizuda.easy.retry.server.common.cache;
|
package com.aizuda.easy.retry.server.common.cache;
|
||||||
|
|
||||||
import cn.hutool.core.lang.Pair;
|
import cn.hutool.core.util.StrUtil;
|
||||||
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.context.SpringContext;
|
import com.aizuda.easy.retry.common.core.context.SpringContext;
|
||||||
import com.aizuda.easy.retry.common.log.EasyRetryLog;
|
import com.aizuda.easy.retry.common.log.EasyRetryLog;
|
||||||
import com.aizuda.easy.retry.server.common.Lifecycle;
|
import com.aizuda.easy.retry.server.common.Lifecycle;
|
||||||
|
import com.aizuda.easy.retry.server.common.triple.Pair;
|
||||||
import com.aizuda.easy.retry.template.datasource.access.AccessTemplate;
|
import com.aizuda.easy.retry.template.datasource.access.AccessTemplate;
|
||||||
import com.aizuda.easy.retry.template.datasource.persistence.po.GroupConfig;
|
import com.aizuda.easy.retry.template.datasource.persistence.po.GroupConfig;
|
||||||
import com.google.common.cache.Cache;
|
import com.google.common.cache.Cache;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,26 +20,31 @@ import java.util.concurrent.TimeUnit;
|
|||||||
* @date 2024-03-29 23:15:26
|
* @date 2024-03-29 23:15:26
|
||||||
* @since 3.2.0
|
* @since 3.2.0
|
||||||
*/
|
*/
|
||||||
|
@Component
|
||||||
public class CacheToken implements Lifecycle {
|
public class CacheToken implements Lifecycle {
|
||||||
|
|
||||||
private static Cache<Pair<String/*groupName*/, String/*namespaceId*/> , String/*Token*/> CACHE;
|
private static Cache<Pair<String/*groupName*/, String/*namespaceId*/>, String/*Token*/> CACHE;
|
||||||
|
|
||||||
public static void add(String groupName, String namespaceId, String token) {
|
public static void add(String groupName, String namespaceId, String token) {
|
||||||
CACHE.put(Pair.of(groupName, namespaceId), token);
|
CACHE.put(Pair.of(groupName, namespaceId), token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String get(String groupName, String namespaceId) throws ExecutionException {
|
public static String get(String groupName, String namespaceId) {
|
||||||
return CACHE.get(Pair.of(groupName, namespaceId), () -> {
|
|
||||||
|
String token = CACHE.getIfPresent(Pair.of(groupName, namespaceId));
|
||||||
|
if (StrUtil.isBlank(token)) {
|
||||||
|
// 从DB获取数据
|
||||||
AccessTemplate template = SpringContext.getBean(AccessTemplate.class);
|
AccessTemplate template = SpringContext.getBean(AccessTemplate.class);
|
||||||
GroupConfig config = template.getGroupConfigAccess().getGroupConfigByGroupName(groupName, namespaceId);
|
GroupConfig config = template.getGroupConfigAccess().getGroupConfigByGroupName(groupName, namespaceId);
|
||||||
if (Objects.isNull(config)) {
|
if (Objects.isNull(config)) {
|
||||||
return SystemConstants.DEFAULT_TOKEN;
|
return SystemConstants.DEFAULT_TOKEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
String token = config.getToken();
|
token = config.getToken();
|
||||||
add(groupName, namespaceId, token);
|
add(groupName, namespaceId, token);
|
||||||
|
}
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -27,7 +27,6 @@ public class RequestBuilder<T, R> {
|
|||||||
private int routeKey;
|
private int routeKey;
|
||||||
private String allocKey;
|
private String allocKey;
|
||||||
private Integer executorTimeout;
|
private Integer executorTimeout;
|
||||||
private String namespaceId;
|
|
||||||
|
|
||||||
public static <T, R> RequestBuilder<T, R> newBuilder() {
|
public static <T, R> RequestBuilder<T, R> newBuilder() {
|
||||||
return new RequestBuilder<>();
|
return new RequestBuilder<>();
|
||||||
@ -88,18 +87,13 @@ public class RequestBuilder<T, R> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RequestBuilder<T, R> namespaceId(String namespaceId) {
|
|
||||||
this.namespaceId = namespaceId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T build() {
|
public T build() {
|
||||||
if (Objects.isNull(clintInterface)) {
|
if (Objects.isNull(clintInterface)) {
|
||||||
throw new EasyRetryServerException("clintInterface cannot be null");
|
throw new EasyRetryServerException("clintInterface cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.notNull(nodeInfo, () -> new EasyRetryServerException("nodeInfo cannot be null"));
|
Assert.notNull(nodeInfo, () -> new EasyRetryServerException("nodeInfo cannot be null"));
|
||||||
Assert.notBlank(namespaceId, () -> new EasyRetryServerException("namespaceId cannot be null"));
|
Assert.notBlank(nodeInfo.getNamespaceId(), () -> new EasyRetryServerException("namespaceId cannot be null"));
|
||||||
|
|
||||||
if (failover) {
|
if (failover) {
|
||||||
Assert.isTrue(routeKey > 0, () -> new EasyRetryServerException("routeKey cannot be null"));
|
Assert.isTrue(routeKey > 0, () -> new EasyRetryServerException("routeKey cannot be null"));
|
||||||
@ -113,7 +107,7 @@ public class RequestBuilder<T, R> {
|
|||||||
|
|
||||||
RpcClientInvokeHandler clientInvokeHandler = new RpcClientInvokeHandler(
|
RpcClientInvokeHandler clientInvokeHandler = new RpcClientInvokeHandler(
|
||||||
nodeInfo.getGroupName(), nodeInfo, failRetry, retryTimes, retryInterval,
|
nodeInfo.getGroupName(), nodeInfo, failRetry, retryTimes, retryInterval,
|
||||||
retryListener, routeKey, allocKey, failover, executorTimeout, namespaceId);
|
retryListener, routeKey, allocKey, failover, executorTimeout, nodeInfo.getNamespaceId());
|
||||||
|
|
||||||
return (T) Proxy.newProxyInstance(clintInterface.getClassLoader(),
|
return (T) Proxy.newProxyInstance(clintInterface.getClassLoader(),
|
||||||
new Class[]{clintInterface}, clientInvokeHandler);
|
new Class[]{clintInterface}, clientInvokeHandler);
|
||||||
|
@ -9,6 +9,7 @@ import com.aizuda.easy.retry.common.core.model.Result;
|
|||||||
import com.aizuda.easy.retry.common.core.util.NetUtil;
|
import com.aizuda.easy.retry.common.core.util.NetUtil;
|
||||||
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.cache.CacheRegisterTable;
|
import com.aizuda.easy.retry.server.common.cache.CacheRegisterTable;
|
||||||
|
import com.aizuda.easy.retry.server.common.cache.CacheToken;
|
||||||
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;
|
||||||
import com.aizuda.easy.retry.server.common.client.annotation.Mapping;
|
import com.aizuda.easy.retry.server.common.client.annotation.Mapping;
|
||||||
@ -142,6 +143,9 @@ public class RpcClientInvokeHandler implements InvocationHandler {
|
|||||||
requestHeaders.set(RequestInterceptor.TIMEOUT_TIME, String.valueOf(executorTimeout));
|
requestHeaders.set(RequestInterceptor.TIMEOUT_TIME, String.valueOf(executorTimeout));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 统一设置Token
|
||||||
|
requestHeaders.set(SystemConstants.EASY_RETRY_AUTH_TOKEN, CacheToken.get(groupName, namespaceId));
|
||||||
|
|
||||||
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
|
||||||
|
@ -17,6 +17,7 @@ public abstract class GetHttpRequestHandler implements HttpRequestHandler {
|
|||||||
@Override
|
@Override
|
||||||
public String doHandler(String content, UrlBuilder builder, HttpHeaders headers) {
|
public String doHandler(String content, UrlBuilder builder, HttpHeaders headers) {
|
||||||
UrlQuery query = builder.getQuery();
|
UrlQuery query = builder.getQuery();
|
||||||
|
|
||||||
return doHandler(content, query, headers);
|
return doHandler(content, query, headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ public abstract class PostHttpRequestHandler implements HttpRequestHandler {
|
|||||||
@Override
|
@Override
|
||||||
public String doHandler(String content, UrlBuilder builder, HttpHeaders headers) {
|
public String doHandler(String content, UrlBuilder builder, HttpHeaders headers) {
|
||||||
UrlQuery query = builder.getQuery();
|
UrlQuery query = builder.getQuery();
|
||||||
|
|
||||||
return doHandler(content, query, headers);
|
return doHandler(content, query, headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,9 @@ import com.aizuda.easy.retry.server.common.handler.ServerNodeBalance;
|
|||||||
import com.aizuda.easy.retry.template.datasource.persistence.po.ServerNode;
|
import com.aizuda.easy.retry.template.datasource.persistence.po.ServerNode;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -26,10 +28,12 @@ import java.time.LocalDateTime;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 服务端注册
|
* 服务端注册
|
||||||
@ -96,8 +100,20 @@ public class ServerRegister extends AbstractRegister {
|
|||||||
try {
|
try {
|
||||||
// 同步当前POD消费的组的节点信息
|
// 同步当前POD消费的组的节点信息
|
||||||
// netty的client只会注册到一个服务端,若组分配的和client连接的不是一个POD则会导致当前POD没有其他客户端的注册信息
|
// netty的client只会注册到一个服务端,若组分配的和client连接的不是一个POD则会导致当前POD没有其他客户端的注册信息
|
||||||
ConcurrentMap<String /*groupName*/, String/*namespaceId*/> allConsumerGroupName = CacheConsumerGroup.getAllConsumerGroupName();
|
ConcurrentMap<String /*groupName*/, Set<String>/*namespaceId*/> allConsumerGroupName = CacheConsumerGroup.getAllConsumerGroupName();
|
||||||
if (!CollectionUtils.isEmpty(allConsumerGroupName)) {
|
if (!CollectionUtils.isEmpty(allConsumerGroupName)) {
|
||||||
|
|
||||||
|
Set<String> namespaceIdSets = allConsumerGroupName.values().stream().reduce((a, b) -> {
|
||||||
|
Set<String> set = Sets.newHashSet();
|
||||||
|
set.addAll(a);
|
||||||
|
set.addAll(b);
|
||||||
|
return set;
|
||||||
|
}).orElse(Sets.newHashSet());
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(namespaceIdSets)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
List<ServerNode> serverNodes = serverNodeMapper.selectList(
|
List<ServerNode> serverNodes = serverNodeMapper.selectList(
|
||||||
new LambdaQueryWrapper<ServerNode>()
|
new LambdaQueryWrapper<ServerNode>()
|
||||||
.eq(ServerNode::getNodeType, NodeTypeEnum.CLIENT.getType())
|
.eq(ServerNode::getNodeType, NodeTypeEnum.CLIENT.getType())
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
package com.aizuda.easy.retry.server.common.triple;
|
||||||
|
|
||||||
|
import com.aizuda.easy.retry.common.core.exception.EasyRetryCommonException;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author: xiaowoniu
|
||||||
|
* @date : 2024-03-30
|
||||||
|
* @since : 3.2.0
|
||||||
|
*/
|
||||||
|
public final class ImmutablePair<L, R> extends Pair<L, R>{
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 4954918890077093841L;
|
||||||
|
|
||||||
|
public final L left;
|
||||||
|
public final R right;
|
||||||
|
|
||||||
|
|
||||||
|
public static <L, R> ImmutablePair<L, R> of(final L left, final R right) {
|
||||||
|
return new ImmutablePair<L, R>(left, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ImmutablePair(final L left, final R right) {
|
||||||
|
super();
|
||||||
|
this.left = left;
|
||||||
|
this.right = right;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public L getLeft() {
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R getRight() {
|
||||||
|
return right;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public R setValue(final R value) {
|
||||||
|
throw new EasyRetryCommonException("非法操作");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package com.aizuda.easy.retry.server.common.triple;
|
package com.aizuda.easy.retry.server.common.triple;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author: xiaowoniu
|
* @author: xiaowoniu
|
||||||
* @date : 2023-11-24 08:56
|
* @date : 2023-11-24 08:56
|
||||||
@ -7,11 +9,12 @@ package com.aizuda.easy.retry.server.common.triple;
|
|||||||
*/
|
*/
|
||||||
public final class ImmutableTriple<L, M, R> extends Triple<L, M, R> {
|
public final class ImmutableTriple<L, M, R> extends Triple<L, M, R> {
|
||||||
|
|
||||||
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public final L left;
|
private final L left;
|
||||||
public final M middle;
|
private final M middle;
|
||||||
public final R right;
|
private final R right;
|
||||||
|
|
||||||
public static <L, M, R> ImmutableTriple<L, M, R> of(final L left, final M middle, final R right) {
|
public static <L, M, R> ImmutableTriple<L, M, R> of(final L left, final M middle, final R right) {
|
||||||
return new ImmutableTriple<>(left, middle, right);
|
return new ImmutableTriple<>(left, middle, right);
|
||||||
|
@ -0,0 +1,84 @@
|
|||||||
|
package com.aizuda.easy.retry.server.common.triple;
|
||||||
|
|
||||||
|
import cn.hutool.core.builder.CompareToBuilder;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author: xiaowoniu
|
||||||
|
* @date : 2024-03-30
|
||||||
|
* @since : 3.2.0
|
||||||
|
*/
|
||||||
|
public abstract class Pair<L, R> implements Map.Entry<L, R>, Comparable<Pair<L, R>>, Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public static <L, R> Pair<L, R> of(final L left, final R right) {
|
||||||
|
return new ImmutablePair<>(left, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract L getLeft();
|
||||||
|
|
||||||
|
|
||||||
|
public abstract R getRight();
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final L getKey() {
|
||||||
|
return getLeft();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R getValue() {
|
||||||
|
return getRight();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(final Pair<L, R> other) {
|
||||||
|
return new CompareToBuilder().append(getLeft(), other.getLeft())
|
||||||
|
.append(getRight(), other.getRight()).toComparison();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
if (obj == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj instanceof Map.Entry<?, ?>) {
|
||||||
|
final Map.Entry<?, ?> other = (Map.Entry<?, ?>) obj;
|
||||||
|
return Objects.equals(getKey(), other.getKey())
|
||||||
|
&& Objects.equals(getValue(), other.getValue());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Returns a suitable hash code.
|
||||||
|
* The hash code follows the definition in {@code Map.Entry}.</p>
|
||||||
|
*
|
||||||
|
* @return the hash code
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return (getKey() == null ? 0 : getKey().hashCode()) ^
|
||||||
|
(getValue() == null ? 0 : getValue().hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Returns a String representation of this pair using the format {@code ($left,$right)}.</p>
|
||||||
|
*
|
||||||
|
* @return a string describing this object, not null
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "(" + getLeft() + ',' + getRight() + ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString(final String format) {
|
||||||
|
return String.format(format, getLeft(), getRight());
|
||||||
|
}
|
||||||
|
}
|
@ -148,7 +148,6 @@ public class RequestClientActor extends AbstractActor {
|
|||||||
boolean retry = realJobExecutorDTO.isRetry();
|
boolean retry = realJobExecutorDTO.isRetry();
|
||||||
return RequestBuilder.<JobRpcClient, Result>newBuilder()
|
return RequestBuilder.<JobRpcClient, Result>newBuilder()
|
||||||
.nodeInfo(registerNodeInfo)
|
.nodeInfo(registerNodeInfo)
|
||||||
.namespaceId(registerNodeInfo.getNamespaceId())
|
|
||||||
.failRetry(maxRetryTimes > 0 && !retry)
|
.failRetry(maxRetryTimes > 0 && !retry)
|
||||||
.retryTimes(maxRetryTimes)
|
.retryTimes(maxRetryTimes)
|
||||||
.retryInterval(realJobExecutorDTO.getRetryInterval())
|
.retryInterval(realJobExecutorDTO.getRetryInterval())
|
||||||
|
@ -53,7 +53,6 @@ public class RealStopTaskActor extends AbstractActor {
|
|||||||
private Result<Boolean> requestClient(RealStopTaskInstanceDTO realStopTaskInstanceDTO, RegisterNodeInfo registerNodeInfo) {
|
private Result<Boolean> requestClient(RealStopTaskInstanceDTO realStopTaskInstanceDTO, RegisterNodeInfo registerNodeInfo) {
|
||||||
JobRpcClient rpcClient = RequestBuilder.<JobRpcClient, Result>newBuilder()
|
JobRpcClient rpcClient = RequestBuilder.<JobRpcClient, Result>newBuilder()
|
||||||
.nodeInfo(registerNodeInfo)
|
.nodeInfo(registerNodeInfo)
|
||||||
.namespaceId(registerNodeInfo.getNamespaceId())
|
|
||||||
.failRetry(Boolean.TRUE)
|
.failRetry(Boolean.TRUE)
|
||||||
.retryTimes(3)
|
.retryTimes(3)
|
||||||
.retryInterval(1)
|
.retryInterval(1)
|
||||||
|
@ -12,6 +12,7 @@ import com.aizuda.easy.retry.server.common.client.RequestMethod;
|
|||||||
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;
|
||||||
import com.aizuda.easy.retry.server.common.client.annotation.Mapping;
|
import com.aizuda.easy.retry.server.common.client.annotation.Mapping;
|
||||||
|
import com.aizuda.easy.retry.server.model.dto.ConfigDTO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 调用客户端接口
|
* 调用客户端接口
|
||||||
@ -31,4 +32,7 @@ public interface RetryRpcClient {
|
|||||||
@Mapping(path = "/retry/generate/idempotent-id/v1", method = RequestMethod.POST)
|
@Mapping(path = "/retry/generate/idempotent-id/v1", method = RequestMethod.POST)
|
||||||
Result generateIdempotentId(@Body GenerateRetryIdempotentIdDTO retryCallbackDTO);
|
Result generateIdempotentId(@Body GenerateRetryIdempotentIdDTO retryCallbackDTO);
|
||||||
|
|
||||||
|
@Mapping(path = "/retry/sync/version/v1")
|
||||||
|
Result syncConfig(@Body ConfigDTO configDTO);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,6 @@ public class ExecCallbackUnitActor extends AbstractActor {
|
|||||||
|
|
||||||
RetryRpcClient rpcClient = RequestBuilder.<RetryRpcClient, Result>newBuilder()
|
RetryRpcClient rpcClient = RequestBuilder.<RetryRpcClient, Result>newBuilder()
|
||||||
.nodeInfo(serverNode)
|
.nodeInfo(serverNode)
|
||||||
.namespaceId(serverNode.getNamespaceId())
|
|
||||||
.failover(Boolean.TRUE)
|
.failover(Boolean.TRUE)
|
||||||
.routeKey(sceneConfig.getRouteKey())
|
.routeKey(sceneConfig.getRouteKey())
|
||||||
.allocKey(sceneConfig.getSceneName())
|
.allocKey(sceneConfig.getSceneName())
|
||||||
|
@ -139,7 +139,6 @@ public class ExecUnitActor extends AbstractActor {
|
|||||||
|
|
||||||
RetryRpcClient rpcClient = RequestBuilder.<RetryRpcClient, Result>newBuilder()
|
RetryRpcClient rpcClient = RequestBuilder.<RetryRpcClient, Result>newBuilder()
|
||||||
.nodeInfo(serverNode)
|
.nodeInfo(serverNode)
|
||||||
.namespaceId(serverNode.getNamespaceId())
|
|
||||||
.failover(Boolean.TRUE)
|
.failover(Boolean.TRUE)
|
||||||
.allocKey(retryTask.getSceneName())
|
.allocKey(retryTask.getSceneName())
|
||||||
.routeKey(sceneConfig.getRouteKey())
|
.routeKey(sceneConfig.getRouteKey())
|
||||||
|
@ -1,21 +1,18 @@
|
|||||||
package com.aizuda.easy.retry.server.retry.task.support.handler;
|
package com.aizuda.easy.retry.server.retry.task.support.handler;
|
||||||
|
|
||||||
import cn.hutool.core.lang.Pair;
|
|
||||||
import com.aizuda.easy.retry.common.core.util.NetUtil;
|
|
||||||
import com.aizuda.easy.retry.common.log.EasyRetryLog;
|
import com.aizuda.easy.retry.common.log.EasyRetryLog;
|
||||||
import com.aizuda.easy.retry.common.core.model.Result;
|
import com.aizuda.easy.retry.common.core.model.Result;
|
||||||
import com.aizuda.easy.retry.server.common.Lifecycle;
|
import com.aizuda.easy.retry.server.common.Lifecycle;
|
||||||
|
import com.aizuda.easy.retry.server.common.client.RequestBuilder;
|
||||||
import com.aizuda.easy.retry.server.common.dto.RegisterNodeInfo;
|
import com.aizuda.easy.retry.server.common.dto.RegisterNodeInfo;
|
||||||
import com.aizuda.easy.retry.server.model.dto.ConfigDTO;
|
import com.aizuda.easy.retry.server.model.dto.ConfigDTO;
|
||||||
import com.aizuda.easy.retry.server.common.cache.CacheRegisterTable;
|
import com.aizuda.easy.retry.server.common.cache.CacheRegisterTable;
|
||||||
|
import com.aizuda.easy.retry.server.retry.task.client.RetryRpcClient;
|
||||||
import com.aizuda.easy.retry.server.retry.task.dto.ConfigSyncTask;
|
import com.aizuda.easy.retry.server.retry.task.dto.ConfigSyncTask;
|
||||||
import com.aizuda.easy.retry.template.datasource.access.AccessTemplate;
|
import com.aizuda.easy.retry.template.datasource.access.AccessTemplate;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.client.RestTemplate;
|
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
@ -29,16 +26,11 @@ import java.util.concurrent.TimeUnit;
|
|||||||
* @since 1.6.0
|
* @since 1.6.0
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@RequiredArgsConstructor
|
||||||
public class ConfigVersionSyncHandler implements Lifecycle, Runnable {
|
public class ConfigVersionSyncHandler implements Lifecycle, Runnable {
|
||||||
|
|
||||||
private static final LinkedBlockingQueue<ConfigSyncTask> QUEUE = new LinkedBlockingQueue<>(256);
|
private static final LinkedBlockingQueue<ConfigSyncTask> QUEUE = new LinkedBlockingQueue<>(256);
|
||||||
public Thread THREAD = null;
|
public Thread THREAD = null;
|
||||||
@Autowired
|
protected final AccessTemplate accessTemplate;
|
||||||
private RestTemplate restTemplate;
|
|
||||||
@Autowired
|
|
||||||
protected AccessTemplate accessTemplate;
|
|
||||||
private static final String SYNC_VERSION_V1 = "/retry/sync/version/v1";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加任务
|
* 添加任务
|
||||||
@ -59,8 +51,8 @@ public class ConfigVersionSyncHandler implements Lifecycle, Runnable {
|
|||||||
/**
|
/**
|
||||||
* 同步版本
|
* 同步版本
|
||||||
*
|
*
|
||||||
* @param groupName
|
* @param groupName 组
|
||||||
* @param namespaceId
|
* @param namespaceId 空间id
|
||||||
*/
|
*/
|
||||||
public void syncVersion(String groupName, final String namespaceId) {
|
public void syncVersion(String groupName, final String namespaceId) {
|
||||||
|
|
||||||
@ -69,11 +61,11 @@ public class ConfigVersionSyncHandler implements Lifecycle, Runnable {
|
|||||||
// 同步版本到每个客户端节点
|
// 同步版本到每个客户端节点
|
||||||
for (final RegisterNodeInfo registerNodeInfo : serverNodeSet) {
|
for (final RegisterNodeInfo registerNodeInfo : serverNodeSet) {
|
||||||
ConfigDTO configDTO = accessTemplate.getGroupConfigAccess().getConfigInfo(groupName, namespaceId);
|
ConfigDTO configDTO = accessTemplate.getGroupConfigAccess().getConfigInfo(groupName, namespaceId);
|
||||||
|
RetryRpcClient rpcClient = RequestBuilder.<RetryRpcClient, Result>newBuilder()
|
||||||
String url = NetUtil.getUrl(registerNodeInfo.getHostIp(), registerNodeInfo.getHostPort(),
|
.nodeInfo(registerNodeInfo)
|
||||||
registerNodeInfo.getContextPath());
|
.client(RetryRpcClient.class)
|
||||||
Result result = restTemplate.postForObject(url.concat(SYNC_VERSION_V1), configDTO, Result.class);
|
.build();
|
||||||
EasyRetryLog.LOCAL.info("同步结果 [{}]", result);
|
EasyRetryLog.LOCAL.info("同步结果 [{}]", rpcClient.syncConfig(configDTO));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
EasyRetryLog.LOCAL.error("version sync error. groupName:[{}]", groupName, e);
|
EasyRetryLog.LOCAL.error("version sync error. groupName:[{}]", groupName, e);
|
||||||
@ -111,8 +103,7 @@ public class ConfigVersionSyncHandler implements Lifecycle, Runnable {
|
|||||||
try {
|
try {
|
||||||
// 防止刷的过快,休眠1s
|
// 防止刷的过快,休眠1s
|
||||||
TimeUnit.SECONDS.sleep(1);
|
TimeUnit.SECONDS.sleep(1);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException ignored) {
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,13 @@ package com.aizuda.easy.retry.server.retry.task.support.retry;
|
|||||||
|
|
||||||
import akka.actor.ActorRef;
|
import akka.actor.ActorRef;
|
||||||
import cn.hutool.core.lang.Pair;
|
import cn.hutool.core.lang.Pair;
|
||||||
|
import com.aizuda.easy.retry.common.log.EasyRetryLog;
|
||||||
import com.aizuda.easy.retry.server.common.akka.ActorGenerator;
|
import com.aizuda.easy.retry.server.common.akka.ActorGenerator;
|
||||||
|
import com.aizuda.easy.retry.server.common.util.DateUtils;
|
||||||
|
import com.aizuda.easy.retry.server.retry.task.dto.RetryLogMetaDTO;
|
||||||
import com.aizuda.easy.retry.server.retry.task.support.FilterStrategy;
|
import com.aizuda.easy.retry.server.retry.task.support.FilterStrategy;
|
||||||
import com.aizuda.easy.retry.server.retry.task.support.RetryContext;
|
import com.aizuda.easy.retry.server.retry.task.support.RetryContext;
|
||||||
|
import com.aizuda.easy.retry.server.retry.task.support.RetryTaskConverter;
|
||||||
import com.aizuda.easy.retry.server.retry.task.support.StopStrategy;
|
import com.aizuda.easy.retry.server.retry.task.support.StopStrategy;
|
||||||
import com.aizuda.easy.retry.server.common.WaitStrategy;
|
import com.aizuda.easy.retry.server.common.WaitStrategy;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -63,13 +67,12 @@ public class RetryExecutor<V> {
|
|||||||
call = callable.call();
|
call = callable.call();
|
||||||
retryContext.setCallResult(call);
|
retryContext.setCallResult(call);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("客户端执行失败: [{}]", retryContext.getRetryTask());
|
RetryLogMetaDTO retryLogMetaDTO = RetryTaskConverter.INSTANCE.toLogMetaDTO(retryContext.getRetryTask());
|
||||||
|
retryLogMetaDTO.setTimestamp(DateUtils.toNowMilli());
|
||||||
|
EasyRetryLog.REMOTE.error("请求客户端执行失败. uniqueId:[{}] <|>{}<|>", retryContext.getRetryTask().getUniqueId(), e);
|
||||||
retryContext.setException(e);
|
retryContext.setException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算下次触发时间
|
|
||||||
// retryContext.getRetryTask().setNextTriggerAt();
|
|
||||||
|
|
||||||
boolean isStop = Boolean.TRUE;
|
boolean isStop = Boolean.TRUE;
|
||||||
|
|
||||||
// 触发停止策略判断
|
// 触发停止策略判断
|
||||||
|
@ -11,6 +11,7 @@ import com.aizuda.easy.retry.common.core.util.JsonUtil;
|
|||||||
import com.aizuda.easy.retry.server.common.HttpRequestHandler;
|
import com.aizuda.easy.retry.server.common.HttpRequestHandler;
|
||||||
import com.aizuda.easy.retry.server.common.Register;
|
import com.aizuda.easy.retry.server.common.Register;
|
||||||
import com.aizuda.easy.retry.server.common.akka.ActorGenerator;
|
import com.aizuda.easy.retry.server.common.akka.ActorGenerator;
|
||||||
|
import com.aizuda.easy.retry.server.common.cache.CacheToken;
|
||||||
import com.aizuda.easy.retry.server.common.dto.NettyHttpRequest;
|
import com.aizuda.easy.retry.server.common.dto.NettyHttpRequest;
|
||||||
import com.aizuda.easy.retry.server.common.register.ClientRegister;
|
import com.aizuda.easy.retry.server.common.register.ClientRegister;
|
||||||
import com.aizuda.easy.retry.server.common.register.RegisterContext;
|
import com.aizuda.easy.retry.server.common.register.RegisterContext;
|
||||||
@ -88,6 +89,12 @@ public class RequestHandlerActor extends AbstractActor {
|
|||||||
String groupName = headers.get(HeadersEnum.GROUP_NAME.getKey());
|
String groupName = headers.get(HeadersEnum.GROUP_NAME.getKey());
|
||||||
String contextPath = headers.get(HeadersEnum.CONTEXT_PATH.getKey());
|
String contextPath = headers.get(HeadersEnum.CONTEXT_PATH.getKey());
|
||||||
String namespace = headers.get(HeadersEnum.NAMESPACE.getKey());
|
String namespace = headers.get(HeadersEnum.NAMESPACE.getKey());
|
||||||
|
String token = headers.get(HeadersEnum.TOKEN.getKey());
|
||||||
|
|
||||||
|
if (!CacheToken.get(groupName, namespace).equals(token)) {
|
||||||
|
EasyRetryLog.LOCAL.error("Token authentication failed. [{}]", token);
|
||||||
|
return JsonUtil.toJsonString(new Result<>(0, "Token authentication failed"));
|
||||||
|
}
|
||||||
|
|
||||||
// 注册版本
|
// 注册版本
|
||||||
RegisterContext registerContext = new RegisterContext();
|
RegisterContext registerContext = new RegisterContext();
|
||||||
@ -103,6 +110,8 @@ public class RequestHandlerActor extends AbstractActor {
|
|||||||
EasyRetryLog.LOCAL.warn("client register error. groupName:[{}]", groupName);
|
EasyRetryLog.LOCAL.warn("client register error. groupName:[{}]", groupName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
UrlBuilder builder = UrlBuilder.ofHttp(uri);
|
UrlBuilder builder = UrlBuilder.ofHttp(uri);
|
||||||
Collection<HttpRequestHandler> httpRequestHandlers = SpringContext.getContext()
|
Collection<HttpRequestHandler> httpRequestHandlers = SpringContext.getContext()
|
||||||
.getBeansOfType(HttpRequestHandler.class).values();
|
.getBeansOfType(HttpRequestHandler.class).values();
|
||||||
|
@ -249,7 +249,6 @@ public class RetryTaskServiceImpl implements RetryTaskService {
|
|||||||
|
|
||||||
RetryRpcClient rpcClient = RequestBuilder.<RetryRpcClient, Result>newBuilder()
|
RetryRpcClient rpcClient = RequestBuilder.<RetryRpcClient, Result>newBuilder()
|
||||||
.nodeInfo(serverNode)
|
.nodeInfo(serverNode)
|
||||||
.namespaceId(serverNode.getNamespaceId())
|
|
||||||
.client(RetryRpcClient.class)
|
.client(RetryRpcClient.class)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user